0Pricing
Python Academy · درس

تحليل الأداء باستخدام 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 functions

line_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 loop

py-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 يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. عدّ المراجع في CPython
  2. جامع البيانات المهملة والمراجع الدورية
  3. تحليل الأداء باستخدام cProfile وline_profiler
  4. تحليل الذاكرة باستخدام tracemalloc
← العودة إلى Python Academy