profiling --- پروفایل‌گیرهای پایتون

اضافه شده در نسخه‌ی 3.15.

کد منبع: Lib/profiling/


آشنایی با پروفایل‌گیری

یک profile مجموعه‌ای از آماره‌ها است که توصیف می‌کند بخش‌های مختلف یک برنامه با چه تناوبی و برای چه مدت‌زمانی اجرا می‌شوند. این آماره‌ها به شناسایی گلوگاه‌های عملکردی کمک کرده و تلاش‌های بهینه‌سازی را هدایت می‌کنند. پایتون دو رویکرد اساساً متفاوت برای جمع‌آوری این اطلاعات ارائه می‌دهد: نمونه‌برداری آماری و ردیابی قطعی (deterministic).

بسته‌ی profiling ابزارهای پروفایل‌گیری توکار پایتون را تحت یک فضای نام واحد سازمان‌دهی می‌کند. این بسته شامل دو زیرماژول است که هر کدام متدولوژی پروفایل‌گیری متفاوتی را پیاده‌سازی می‌کنند:

profiling.sampling

یک پروفایل‌گیر آماری که به‌طور دوره‌ای از پشته‌ی فراخوانی نمونه‌برداری می‌کند. اسکریپت‌ها را مستقیماً اجرا کنید یا از طریق PID به فرایندهای در حال اجرا متصل شوید. این ماژول چندین فرمت خروجی (نمودارهای شعله‌ای، نقشه‌های حرارتی، Firefox Profiler)، تحلیل GIL، پیگیری GC و چندین حالت پروفایل‌گیری (زمان واقعی، CPU، GIL) را با عملاً هیچ سرباری فراهم می‌کند.

profiling.tracing

یک پروفایل‌گیر قطعی که هر فراخوانی تابع، بازگشت و رویداد استثنا را ردیابی می‌کند. این ماژول تعداد دقیق فراخوانی‌ها و اطلاعات زمانی دقیق را فراهم می‌کند و تمام فراخوانی‌ها، از جمله توابع بسیار سریع را ثبت می‌کند.

نکته

ماژول‌های پروفایل‌گیر به‌گونه‌ای طراحی شده‌اند که پروفایل اجرایی یک برنامه‌ی مشخص را ارائه دهند، نه برای اهداف بنچ‌مارک (سنجش کارایی). برای بنچ‌مارک، از ماژول timeit استفاده کنید که اندازه‌گیری‌های زمانی نسبتاً دقیقی را فراهم می‌کند. این تمایز به‌ویژه هنگام مقایسه‌ی کد پایتون با کد C اهمیت دارد: پروفایل‌گیرهای قطعی برای کد پایتون سربار ایجاد می‌کنند اما برای توابع سطح C خیر، که این موضوع می‌تواند مقایسه‌ها را دچار انحراف کند.

انتخاب یک پروفایل‌گیر

برای بیشتر تحلیل‌های عملکردی، از پروفایل‌گیر آماری (profiling.sampling) استفاده کنید. این پروفایل‌گیر حداقل سربار را دارد، هم برای توسعه و هم برای محیط تولید کار می‌کند و گزینه‌های بصری‌سازی غنی از جمله نمودارهای شعله‌ای، نقشه‌های حرارتی، تحلیل GIL و موارد دیگر را فراهم می‌کند.

هنگامی که به تعداد دقیق فراخوانی‌ها نیاز دارید و نمی‌خواهید هیچ فراخوانی تابعی از دست برود، از پروفایل‌گیر قطعی (profiling.tracing) استفاده کنید. از آنجا که این ماژول هر فراخوانی تابع و بازگشتی را ابزاربندی می‌کند، حتی توابع بسیار سریعی را که بین بازه‌های نمونه‌برداری کامل می‌شوند نیز ثبت خواهد کرد. نکته‌ی منفی، سربار بالاتر است.

جدول زیر تفاوت‌های کلیدی را خلاصه می‌کند:

ویژگی

نمونه‌برداری آماری (profiling.sampling)

قطعی (profiling.tracing)

سربار

عملاً صفر

متوسط

دقت

برآورد آماری

تعداد دقیق فراخوانی‌ها

قالب‌های خروجی

pstats، نمودار شعله‌ای (flame graph)، نقشه‌ی حرارتی (heatmap)، gecko، فشرده‌شده (collapsed)

pstats

حالت‌های پروفایل‌گیری

زمان دیوار (Wall-clock)، پردازنده، GIL

زمان دیوار (Wall-clock)

قاب‌های ویژه

مدیریت حافظه (GC)، بومی (پسوندهای C)

ناموجود

اتصال به PID

بله

خیر

چه زمانی از نمونه‌برداری آماری استفاده کنید

پروفایل‌گیر آماری (profiling.sampling) برای بیشتر وظایف تحلیل کارایی پیشنهاد می‌شود. از آن درست مانند profiling.tracing استفاده کنید:

python -m profiling.sampling run script.py

یکی از نقاط قوت اصلی پروفایل‌گیر نمونه‌برداری، تنوع قالب‌های خروجی آن است. فراتر از جدول‌های سنتی pstats، این ابزار می‌تواند نمودارهای شعله‌ای تعاملی تولید کند که سلسله‌مراتب فراخوانی را مصورسازی می‌کنند، نقشه‌های حرارتی منبع در سطح سطر که دقیقاً نشان می‌دهند زمان در کک شما کجا صرف شده است، و خروجی پروفایل‌گیر فایرفاکس را برای تحلیل مبتنی بر خط زمانی فراهم کند.

این پروفایل‌گیر همچنین بینشی نسبت به رفتار مفسر پایتون فراهم می‌کند که پروفایل‌گیری قطعی نمی‌تواند ثبت کند. از --mode gil برای شناسایی رقابت بر سر GIL در کد چندنخی، از --mode cpu برای اندازه‌گیری زمان واقعی پردازنده به غیر از انتظارهای I/O، یا بررسی قاب‌های <GC> برای درک سربار زباله‌روبی استفاده کنید. گزینه‌ی --native زمان صرف‌شده در پسوندهای C را آشکار می‌کند و به تفکیک سربار پایتون از کارایی کتابخانه کمک می‌کند.

برای برنامه‌های چندنخی، گزینه‌ی -a همه نخ‌ها را به‌طور هم‌زمان نمونه‌برداری می‌کند و نشان می‌دهد کار چگونه توزیع شده است. همچنین برای اشکال‌زدایی در محیط تولید، دستور attach به هر فرایند در حال اجرای پایتون از طریق PID متصل می‌شود بدون اینکه نیازی به راه‌اندازی مجدد یا تغییرات کد باشد.

چه زمانی از ردیابی قطعی استفاده کنیم

پروفایل‌گیر قطعی (profiling.tracing) تمام فراخوانی‌ها و بازگشت‌های تابع را ابزارگذاری می‌کند. این رویکرد سربار بالاتری نسبت به نمونه‌برداری دارد، اما پوشش کاملی از اجرای برنامه را تضمین می‌کند.

دلیل اصلی برای انتخاب پروفایل‌گیری قطعی زمانی است که به تعداد دقیق فراخوانی‌ها نیاز دارید. پروفایل‌گیری آماری بسامد را بر اساس نمونه‌برداری تخمین می‌زند، که ممکن است توابع عمرکوتاهی را که بین نمونه‌ها کامل می‌شوند، کمتر از مقدار واقعی بشاند. اگر نیاز دارید تأیید کنید که یک بهینه‌سازی واقعاً تعداد فراخوانی‌های تابع را کاهش داده است، یا اگر می‌خواهید گراف کامل فراخوانی‌ها را برای درک روابط فراخواننده و فراخوانده‌شده ردگیری کنید، پروفایل‌گیری قطعی انتخاب درستی است.

پروفایل‌گیری قطعی همچنین در ثبت توابع کوتاه‌مدتی که در مایکروثانیه‌ها اجرا می‌شوند عملکرد بسیار خوبی دارد. چنین توابعی ممکن است به اندازه کافی در نمونه‌های آماری ظاهر نشوند، اما پروفایل‌گیری قطعی هر فراخوانی را صرف‌نظر از مدت‌زمان آن ثبت می‌کند.

شروع سریع

این بخش حداقل گام‌های لازم برای شروع پروفایل‌گیری را ارائه می‌دهد. برای مستندات کامل، صفحات اختصاصی هر پروفایل‌گیر را ببینید.

پروفایل‌گیری آماری

برای پروفایل‌گیری یک اسکریپت، از ماژول profiling.sampling به همراه دستور run استفاده کنید:

python -m profiling.sampling run script.py
python -m profiling.sampling run -m mypackage.module

این کار اسکریپت را تحت پروفایل‌گیر اجرا می‌کند و خلاصه‌ای از محل صرف زمان را چاپ می‌کند. برای یک نمودار شعله‌ی تعاملی:

python -m profiling.sampling run --flamegraph script.py

برای پروفایل‌گیری یک فرایند در حال اجرا، از دستور attach به همراه شناسه‌ی فرایند استفاده کنید:

python -m profiling.sampling attach 1234

برای تنظیمات سفارشی، بازه‌ی نمونه‌برداری (بر حسب مایکروثانیه) و مدت‌زمان (بر حسب ثانیه) را مشخص کنید:

python -m profiling.sampling run -i 50 -d 30 script.py

پروفایل‌گیری قطعی

برای پروفایل‌گیری یک اسکریپت از خط فرمان:

python -m profiling.tracing script.py

برای پروفایل‌گیری بخشی از کد به شکل برنامه‌نویسی‌شده:

import profiling.tracing
profiling.tracing.run('my_function()')

این کد داده‌شده را تحت پروفایل‌گیر اجرا می‌کند و خلاصه‌ای شامل تعداد دقیق فراخوانی‌های تابع و زمان‌بندی را چاپ می‌کند.

درک خروجی پروفایل‌گیری

هر دو پروفایل‌گیر آمار در سطح تابع را جمع‌آوری می‌کنند، البته آن‌ها را در قالب‌های متفاوتی نمایش می‌دهند. پروفایل‌گیر نمونه‌برداری تجسم‌های متعددی (نمودارهای شعله‌ای، نقشه‌های حرارتی، پروفایل‌گیر فایرفاکس، جدول‌های pstats) را ارائه می‌دهد، در حالی که پروفایل‌گیر قطعی (deterministic) خروجی سازگار با pstats تولید می‌کند. صرف‌نظر از قالب، مفاهیم زیربنایی یکسان هستند.

مفاهیم کلیدی پروفایل‌گیری:

زمان مستقیم (که زمان خود یا self time یا tottime نیز نامیده می‌شود)

زمانی که صرف اجرای کد در خودِ تابع می‌شود، به استثنای زمانی که در توابع فراخوانی‌شده توسط آن صرف شده است. زمان مستقیم بالا نشان می‌دهد که تابع شامل عملیات پرهزینه‌ای است.

زمان تجمعی (که زمان کل یا total time یا cumtime نیز نامیده می‌شود)

زمانی که در تابع و تمام توابع فراخوانی‌شده توسط آن صرف شده است. این معیار هزینه کل فراخوانی یک تابع، از جمله کل زیردرخت فراخوانی آن را اندازه‌گیری می‌کند.

تعداد فراخوانی (که ncalls یا نمونه‌ها samples نیز نامیده می‌شود)

تعداد دفعاتی که تابع فراخوانی (قطعی) یا نمونه‌برداری (آماری) شده است. در پروفایل‌گیری قطعی، این مقدار دقیق است. در پروفایل‌گیری آماری، نشان‌دهنده‌ی تعداد دفعاتی است که تابع در یک نمونه‌ی پشته ظاهر شده است.

فراخوانی‌های اولیه

فراخوانی‌هایی که توسط بازگشت (recursion) القا نشده‌اند. هنگامی که یک تابع به صورت بازگشتی اجرا می‌شود، تعداد کل فراخوانی شامل فراخوانی‌های بازگشتی است، اما فراخوانی‌های اولیه فقط ورود اولیه را می‌شمارد. به صورت total/primitive نمایش داده می‌شود (برای مثال، 3/1 به معنای سه فراخوانی کل و یک فراخوانی اولیه است).

روابط فراخواننده/فراخوانی‌شونده (Caller/Callee)

اینکه چه توابعی یک تابع مشخص را فراخوانی کرده‌اند (فراخواننده‌ها) و آن تابع چه توابعی را فراخوانی کرده است (فراخوانی‌شوندگان). نمودارهای شعله‌ای این را به صورت مستطیل‌های تودرتو تجسم می‌کنند؛ pstats می‌تواند آن را از طریق متدهای print_callers() و print_callees() نمایش دهد.

سازگاری با نسخه‌های قبلی

برای سازگاری عقبگرد، ماژول cProfile به عنوان یک نام مستعار برای profiling.tracing در دسترس باقی می‌ماند. کدهای موجودی که از import cProfile استفاده می‌کنند، بدون هیچ تغییری در تمام نسخه‌های آینده‌ی پایتون به کار خود ادامه خواهند داد.

منسوخ شده از نسخه‌ی 3.15: ماژول خالص پایتون profile منسوخ شده است و در پایتون ۳.۱۷ حذف خواهد شد. به‌جای آن از profiling.tracing (یا نام مستعار آن cProfile) استفاده کنید. برای راهنمایی مهاجرت به profile مراجعه کنید.

همچنین ببینید

profiling.sampling

پروفایل‌گیر نمونه‌برداری آماری با نمودارهای شعله‌ای، نقشه‌های حرارتی و تحلیل GIL. برای بیشتر کاربران توصیه می‌شود.

profiling.tracing

پروفایل‌گیر ردیابی قطعی برای تعداد دقیق فراخوانی‌ها.

pstats

تحلیل آماری و قالب‌بندی برای داده‌های پروفایل.

timeit

ماژولی برای اندازه‌گیری زمان اجرای قطعه‌کدهای کوچک.

زیرماژول‌ها