تسريع كود بايثون: دليل تحسين الأداء

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة في تحسين أداء بايثون

اكتسبت لغة بايثون شهرة واسعة بفضل بساطة تركيبها ونظامها البيئي الغني بالمكتبات. ومع ذلك، عند التعامل مع كميات كبيرة من البيانات أو الحسابات الرياضية المعقدة أو التطبيقات عالية التحميل، تظهر تحديات تتعلق بالأداء. في هذا الدليل، سنستعرض طرقًا مجربة لتسريع كود بايثون بدءًا من التقنيات الأساسية وصولًا إلى الحلول المتقدمة.

الأسباب الرئيسية لبطء أداء بايثون

الخصائص المعمارية للغة

الطبيعة التفسيرية للغة - يتم تنفيذ بايثون سطرًا بسطر عبر المفسر، مما يضيف تكاليف إضافية مقارنة باللغات المترجمة.

الكتابة الديناميكية - يتم التحقق من أنواع البيانات أثناء التنفيذ، مما يتطلب موارد حاسوبية إضافية.

قفل المفسر العام (GIL) - آلية تأمين تحد من تعدد الخيوط الحقيقي في CPython.

الخوارزميات غير المثلى - غالبًا ما يكون هذا هو السبب الرئيسي لضعف الأداء، ويمكن حله باختيار هياكل البيانات والخوارزميات المناسبة.

طرق عملية لتحسين أداء بايثون

1. تحليل أداء الكود

قبل البدء في التحسين، يجب تحديد نقاط الضعف:

import cProfile
import pstats

# تحليل أداء دالة
cProfile.run('your_function()', 'profile_stats')
p = pstats.Stats('profile_stats')
p.sort_stats('cumulative').print_stats(10)

أدوات التحليل:

  • cProfile - محلل أداء مدمج
  • line_profiler - تحليل سطر بسطر
  • memory_profiler - مراقبة استخدام الذاكرة

2. الاستخدام الفعال للدوال المدمجة

الدوال المدمجة في بايثون مكتوبة بلغة C وتعمل بشكل أسرع بكثير من الكود المخصص:

# طريقة بطيئة
total = 0
for i in range(1000000):
    total += i

# طريقة سريعة
total = sum(range(1000000))

# البحث عن أكبر عنصر
# بطيء
max_val = numbers[0]
for num in numbers[1:]:
    if num > max_val:
        max_val = num

# سريع
max_val = max(numbers)

3. تحسين التعامل مع البيانات

استخدام المولدات لتوفير الذاكرة:

# إنشاء قائمة (تستهلك ذاكرة كبيرة)
squares_list = [x**2 for x in range(1000000)]

# مولد (توفير في الذاكرة)
squares_gen = (x**2 for x in range(1000000))

# دالة مولد
def fibonacci_generator():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

اختيار هياكل البيانات المناسبة:

# للبحث عن العناصر استخدم set
large_list = list(range(100000))
large_set = set(range(100000))

# البحث في القائمة O(n)
if 99999 in large_list:
    pass

# البحث في المجموعة O(1)
if 99999 in large_set:
    pass

# لعد العناصر استخدم Counter
from collections import Counter
data = ['a', 'b', 'a', 'c', 'b', 'a']
counter = Counter(data)

4. التوجيه باستخدام NumPy

توفر مكتبة NumPy عمليات عالية الأداء على المصفوفات:

import numpy as np

# بايثون عادي
def python_sum_squares(arr):
    return sum(x**2 for x in arr)

# توجيه NumPy
def numpy_sum_squares(arr):
    np_arr = np.array(arr)
    return np.sum(np_arr**2)

# مثال استخدام
data = list(range(1000000))
# إصدار NumPy سيكون أسرع بـ 10 إلى 50 مرة

5. تحسين الحلقات التكرارية

تجنب العمليات الزائدة داخل الحلقات:

# غير فعال
items = ['apple', 'banana', 'cherry']
for i in range(len(items)):
    print(f"Item {i}: {items[i]}")

# فعال
for i, item in enumerate(items):                

المدونات

توصيات الكتب