تحليل الأداء باستخدام cProfile وline_profiler
اعثر على نقاط الاختناق في المعالج باستخدام cProfile والتحليل سطراً بسطر
تحليل الأداء باستخدام cProfile وline_profiler درس مجاني في Python Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Python Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Python Academy 4 دروس في المجموع.
لماذا نستخدم تحليل الأداء؟
يحدّد تحليل الأداء الدوال التي تستهلك معظم الوقت، ويوجّه جهود تحسين الأداء. احرص دائمًا على تحليل الأداء قبل إجراء التحسينات — ولا تعتمد على التخمين.
import cProfile
def slow():
total = 0
for i in range(1_000_000):
total += i
return total
cProfile.run("slow()")تشغيل cProfile من سطر الأوامر
حلّل أداء نص برمجي كامل من دون تعديله: python -m cProfile -s cumtime script.py. رتّب النتائج حسب cumtime أو tottime أو calls.
# python -m cProfile -s cumtime my_script.py
#
# ncalls tottime percall cumtime percall filename:lineno(function)
# 1000 0.500 0.001 2.100 0.002 utils.py:10(process)cProfile في الشيفرة
أنشئ كائنًا من cProfile.Profile، ثم فعّل محلّل الأداء وعطّله، وبعد ذلك اطبع الإحصاءات باستخدام pstats.
import cProfile, pstats, io
pr = cProfile.Profile()
pr.enable()
# ... code to profile ...
pr.disable()
stream = io.StringIO()
ps = pstats.Stats(pr, stream=stream).sort_stats("cumulative")
ps.print_stats(10) # top 10
print(stream.getvalue())تصفية pstats
صفِّ مخرجات محلّل الأداء لعرض نمط اسم وحدة أو دالة محددة فقط باستخدام print_stats(pattern).
import cProfile, pstats
cProfile.run("my_function()", "profile.out")
stats = pstats.Stats("profile.out")
stats.sort_stats("tottime")
stats.print_stats("mymodule") # only mymodule functionsline_profiler
يعرض line_profiler وقت التنفيذ لكل سطر، وليس لكل دالة فقط، وهذا ضروري للعثور على السطر الأكثر استهلاكًا للوقت داخل الدالة.
# pip install line_profiler
# Decorate target function:
from line_profiler import profile
@profile
def process(data):
result = []
for item in data: # <- which line is slow?
result.append(item*2)
return result
# Run: kernprof -l -v script.pyواجهة سطر أوامر kernprof
يشغّل kernprof -l script.py النص البرمجي مع تفعيل تحليل الأداء لكل سطر؛ ويعرض الخيار -v التقرير فورًا.
# kernprof -l -v script.py
#
# Line # Hits Time Per Hit % Time Line Contents
# ======================================================
# 4 1 2.0 2.0 1.0 result = []
# 5 1000 120.0 0.1 60.0 for item in data:
# 6 1000 80.0 0.1 39.0 result.append(item*2)تحليل الأداء في Jupyter
يوفّر Jupyter أوامر السحر %prun (cProfile) و%lprun (line_profiler).
# In a Jupyter cell:
# %prun -s cumulative my_function(data)
# %load_ext line_profiler
# %lprun -f my_function my_function(data)تحديد نقاط الاختناق
ركّز على الدوال ذات أعلى وقت تراكمي (السلسلة كاملة) وأعلى وقت إجمالي (وقت الدالة نفسها، باستثناء الدوال التي تستدعيها).
# cumtime = total time including callees (find root cause)
# tottime = time in function itself (find where work happens)
#
# Optimise the function with highest tottime firstتجنّب التحسين المبكر
حلّل الأداء أولًا، ثم حسّن عنق الزجاجة الذي أثبت القياس وجوده. من الطرق الشائعة لتسريع Python: استخدام الدوال المضمّنة، ونقل الحلقات إلى NumPy، وتخزين نتائج عمليات البحث المتكررة مؤقتًا، أو استدعاء C عبر ctypes/cffi.
# Before optimising:
# profile shows: process_row() 95% of time
# Speedup: vectorise with NumPy
import numpy as np
arr = np.array(data)
result = arr * 2 # 100x faster than Python looppy-spy: محلّل أداء بالعينات
يحلّل py-spy أداء العمليات قيد التشغيل من دون تعديل الشيفرة، إذ يمكنك إرفاقه بمعرّف عملية حي.
# pip install py-spy
# Profile for 30 s and show flamegraph:
# py-spy top --pid 12345
# py-spy record -o profile.svg --pid 12345 --duration 30المقارنة المعيارية باستخدام timeit
استخدم timeit لإجراء مقارنات معيارية صغيرة لتعبيرات محددة.
import timeit
result = timeit.timeit(
"[x*2 for x in range(1000)]",
number=10_000
)
print(f"{result:.3f} s for 10k runs")تحقّق سريع
ماذا يعرض tottime في تقرير cProfile؟
مراجعة
استخدم cProfile للعثور على الدوال البطيئة، وline_profiler للعثور على السطر البطيء. حلّل الأداء باستخدام -s cumtime للعثور على الأسباب الجذرية. حسّن نقاط الاختناق المثبتة فقط، واستخدم المعالجة المتجهية في NumPy أو التخزين المؤقت أو امتدادات C لتحقيق أكبر المكاسب.
الأسئلة الشائعة
هل درس «تحليل الأداء باستخدام cProfile وline_profiler» مجاني؟
نعم — نص درس «تحليل الأداء باستخدام cProfile وline_profiler» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Python Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Python Academy 4 دروس في المجموع.
ماذا ستتعلم في «تحليل الأداء باستخدام cProfile وline_profiler»؟
اعثر على نقاط الاختناق في المعالج باستخدام cProfile والتحليل سطراً بسطر تتمرن على Python Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Python Academy؟
لا تُشترط خبرة سابقة. Python Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «تحليل الأداء باستخدام cProfile وline_profiler»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Python Academy هذا؟
نعم. كل درس في Python Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- عدّ المراجع في CPython
- جامع البيانات المهملة والمراجع الدورية
- تحليل الأداء باستخدام cProfile وline_profiler
- تحليل الذاكرة باستخدام tracemalloc