سطح مقدماتی (Beginner Level)
پروفایلینگ (Profiling) به معنای تحلیل برنامه برای اندازهگیری پارامترهایی مثل زمان اجرا (Execution Time) یا میزان مصرف حافظه است. در سطح مقدماتی، یاد میگیریم چگونه زمان اجرای تکههای کوچک کد را اندازه بگیریم.
۱. اندازهگیری ساده با time
سادهترین روش، ثبت زمان شروع و پایان یک عملیات است. برای این کار بهتر است از time.perf_counter() استفاده کنید که دقت بالاتری نسبت به time.time() دارد.
مثال ۱: اندازهگیری زمان اجرای یک حلقه ساده.
مثال ۲: مقایسه زمان اجرای دو تابع ساده (لیست معمولی vs لیست کامپریهنشن).
۲. استفاده از ماژول timeit
برای اندازهگیری دقیق تکه کدهای کوچک (Micro-benchmarking)، روش دستی بالا خطا دارد (به دلیل سربار سیستم عامل). ماژول استاندارد timeit این کار را با اجراهای متعدد انجام میدهد تا میانگین دقیقتری ارائه دهد.
مثال ۱: استفاده از timeit برای تست سرعت الحاق رشتهها.
مثال ۲: استفاده از timeit.repeat برای اطمینان بیشتر.
این متد چندین بار تست را تکرار میکند تا کمترین زمان (Best Case) را پیدا کنید.
import timeit
setup_code = "from math import sqrt"
stmt_code = "sqrt(12345)"
# ۵ بار تکرار میکند، هر بار ۱۰،۰۰۰ اجرا
results = timeit.repeat(stmt=stmt_code, setup=setup_code, repeat=5, number=10000)
print(f"All runs: {results}")
print(f"Best time: {min(results)}")
سطح پیشرفته (Professional Level)
در برنامههای بزرگ، اندازهگیری دستی توابع کارآمد نیست. ما نیاز داریم بدانیم کدام تابع بیشترین زمان را مصرف میکند (گلوگاه یا Bottleneck کجاست). برای این کار از Deterministic Profiling با ماژول cProfile استفاده میکنیم.
۱. تحلیل جامع با cProfile
این ماژول تعداد فراخوانیها (ncalls)، زمان خالص تابع (tottime) و زمان تجمعی (cumtime) را گزارش میدهد.
مثال ۱: پروفایل کردن یک اسکریپت کامل درون کد.
مثال ۲: ذخیره خروجی پروفایل در فایل (برای نمایش با ابزارهای گرافیکی مثل SnakeViz).
import cProfile
def heavy_computation():
return [x**2 for x in range(100000)]
# نتیجه را در فایل stats.prof ذخیره میکند
cProfile.run('heavy_computation()', 'stats.prof')
print("Profile data saved to stats.prof")
۲. تحلیل نتایج با pstats
خروجی cProfile به صورت متنی ممکن است شلوغ باشد. با کلاس pstats میتوانیم نتایج را مرتب و فیلتر کنیم.
مثال ۱: مرتبسازی بر اساس زمان تجمعی (Cumulative Time). این روش نشان میدهد کدام تابع (و زیرمجموعههایش) بیشترین زمان برنامه را گرفتهاند.
۳. ساخت دکوریتور پروفایلینگ (Profiling Decorator)
یک روش حرفهای برای دیباگ پرفرمنس، ساختن دکوریتوری است که فقط تابع مورد نظر را پروفایل کند.
مثال ۱: دکوریتور سفارشی با cProfile.
۴. نکات بهینهسازی (Optimization Tips)
بعد از پیدا کردن گلوگاه با پروفایلینگ، باید کد را بهینه کنید.
- نکته ۱: دسترسی به متغیرهای
Localسریعتر ازGlobalاست. - نکته ۲: استفاده از توابع Built-in (مثل
mapیاsum) معمولاً سریعتر از حلقههای پایتونی است چون در C پیادهسازی شدهاند.
مثال: تاثیر استفاده از متغیر لوکال در حلقه.