Working with Profile Data Using pstats

Python Profiling Your Code

SU

Profiling Ma'lumotlari Bilan Ishlash: pstats

Python’da cProfile orqali olingan profiling ma'lumotlarini tahlil qilish uchun alohida kutubxona mavjud — bu pstats deb ataladi. pstats yordamida siz yig'ilgan profiling ma'lumotlarini saralash va filtrlash mumkin.

Keling, pstats moduli yordamida cProfile chiqishining odatdagi formatini qanday tiklashni ko'rib chiqaylik. Buning uchun formatted_output.py nomli faylni yaratamiz:

import pstats
 
def formatted_stats_output(path):
    p = pstats.Stats(path)
    stripped_dirs = p.strip_dirs()
    sorted_stats = stripped_dirs.sort_stats('filename')
    sorted_stats.print_stats()
 
if __name__ == '__main__':
    path = 'profile_output.txt'
    formatted_stats_output(path)

Ushbu misolda, siz pstats modulini import qilasiz va oldingi bo'limda yaratilgan profile_output.txt faylini Stats() yordamida yuklaysiz. Keyin strip_dirs() funksiyasidan foydalanib, fayllarning to'liq yo'llarini olib tashlaysiz, chunki bu ma'lumotlarni chiqarishda ularni ko'rishni istamaysiz. Eslatib o'tamiz, buni bajarganingizda, Stats obyekti o'zgartiriladi va yo'l ma'lumotlari yo'qoladi.

Keyin sort_stats('filename') yordamida profiling ma'lumotlarini fayl nomi bo'yicha saralaysiz. Profiling ma'lumotlarini quyidagi satrlar yordamida saralash mumkin:

  • 'calls' — chaqiruvlar soni
  • 'cumulative' — kümülatif vaqt
  • 'cumtime' — kümülatif vaqt
  • 'file' — fayl nomi
  • 'filename' — fayl nomi
  • 'module' — modul nomi
  • 'ncalls' — chaqiruvlar soni
  • 'pcalls' — asosiy chaqiruvlar soni
  • 'line' — qator raqami
  • 'name' — funksiya nomi
  • 'nfl' — nom/fayl/qator
  • 'stdname' — standart nom
  • 'time' — ichki vaqt
  • 'tottime' — ichki vaqt

Bu satrlarning aksariyati uchun SortKey enumlari mavjud, ular satrlar o'rniga ishlatilishi mumkin.

Endi esa profiling ma'lumotlarini print_stats() orqali chiqarishingiz mumkin.

Mana chiqish:

Tue May 19 21:00:38 2020 profile_output.txt
Ordered by: file name
ncalls tottime percall cumtime percall filename:lineno(function)
1      0.000    0.000    2.502    2.502    profile_test.py:5(quick)
1      0.000    0.000    0.501    0.501    profile_test.py:9(average)
1      0.000    0.000    2.000    2.000    profile_test.py:13(super_slow)
1      0.000    0.000    2.502    2.502    profile_test.py:17(main)
1      0.000    0.000    2.502    2.502    profile_test.py:3(<module>)
1      0.000    0.000    2.502    2.502    {built-in method builtins.exec}
1      0.000    0.000    0.000    0.000    {built-in method builtins.print}
1      0.000    0.000    2.502    1.251    {built-in method time.sleep}

Chiqish unchalik o'xshash emas, ammo juda yaqin! Yuqorida keltirilgan satrlar yordamida chiqishni boshqa yo'llar bilan saralashni sinab ko'ring.

Agar chiqishni filtrlashni xohlasangiz, print_stats() funksiyasiga oddiy ifoda (regular expression) uzatishingiz mumkin. Oddiy ifodalar - bu biror narsani qidirishda foydalanish mumkin bo'lgan belgilardan iborat ketma-ketlikdir. Ular ko'p jihatdan o'z tiliga ega. Python re modulida oddiy ifodalar qo'llab-quvvatlanadi.

Agar profiling ma'lumotlarini faqat main() funksiyasiga tegishli bo'lgan qismlarini ko'rsatishni istasangiz, quyidagi kodni ishlating:

sorted_stats.print_stats('\(main')

Bu yerda oddiy ifoda ochiq qavslarni o'z ichiga oladi, bu Python'ga funksiya nomi bo'yicha moslikni tekshirishni anglatadi. Agar yuqoridagi kodni o'zgartirilgan holatda qayta ishga tushirsangiz, quyidagi chiqishni ko'rasiz:

Tue May 19 21:00:38 2020 profile_output.txt
Ordered by: file name
List reduced from 9 to 1 due to restriction <'\\(main'>
ncalls tottime percall cumtime percall filename:lineno(function)
1      0.000    0.000    2.502    2.502    profile_test.py:17(main)

Shuningdek, pstats'ga ma'lum funksiyalar uchun chaqiruvchi va chaqirilgan funksiyalarni ham chiqarishni so'rashingiz mumkin. Misol uchun, quyidagi kodni yozib, main() funksiyasini kim chaqirganini va main() o'zi kimni chaqirganini ko'rsatish mumkin:

import pstats
 
def formatted_stats_output(path):
    p = pstats.Stats(path)
    stripped_dirs = p.strip_dirs()
    sorted_stats = stripped_dirs.sort_stats('filename')
    sorted_stats.print_callers('\(main')
    sorted_stats.print_callees('\(main')
 
if __name__ == '__main__':
    path = 'profile_output.txt'
    formatted_stats_output(path)

Bu yerda yana (main oddiy ifodasi ishlatiladi, chiqishni faqat main() funksiyasiga moslashtirish uchun. Ushbu kodni ishga tushirganingizda quyidagi chiqishni ko'rasiz:

Ordered by: file name
List reduced from 9 to 1 due to restriction <'\\(main')>
Function was called by...
ncalls tottime cumtime
profile_test.py:17(main) <- 1 0.000 2.502 profile_test.py:3(<module>)

Ordered by: file name
List reduced from 9 to 1 due to restriction <'\\(main')>
Function called...
ncalls tottime cumtime
profile_test.py:17(main) -> 2 0.000 0.000 profile_test.py:5(quick)
profile_test.py:17(main) -> 1 0.000 0.501 profile_test.py:9(average)
profile_test.py:17(main) -> 1 0.000 2.000 profile_test.py:13(super_slow)

callees blokida, main() funksiyasining quick(), average(), va super_slow() funksiyalarini chaqirganini ko'rasiz, bu esa chaqiruvchini muvaffaqiyatli aniqlaganligingizni ko'rsatadi.

Last updated on

On this page

Xato haqida xabar berish