Skip to content

الفصل 32: الأداء والتحسين

مقدمة

الأداء الجيد مهم لتجربة المستخدم. في هذا الفصل سنتعلم كيف نكتب كوداً فعالاً وسريعاً في لغة ص.

قياس الأداء

قياس الزمن

sad
متغير بداية = الآن()

# كود نريد قياس أدائه
متغير مجموع = 0
لكل م في مدى(1، 1000000)
    مجموع = مجموع + م
نهاية

متغير نهاية_الوقت = الآن()
اطبع_سطر("الزمن: " + (نهاية_الوقت - بداية) + " مللي ثانية")

دالة قياس عامة

sad
دالة قياس_أداء(اسم، دالة_الاختبار)
    متغير بداية = الآن()
    متغير نتيجة = دالة_الاختبار()
    متغير المدة = الآن() - بداية
    اطبع_سطر(اسم + ": " + المدة + " مللي ثانية")
    ارجع نتيجة
نهاية

# الاستخدام
قياس_أداء("جمع المليون"، لامدا()
    متغير مجموع = 0
    لكل م في مدى(1، 1000000)
        مجموع = مجموع + م
    نهاية
    ارجع مجموع
نهاية)

تحسين الخوارزميات

اختيار الخوارزمية المناسبة

الخوارزميةالتعقيد الزمنيمناسبة لـ
بحث خطيO(n)مصفوفات صغيرة غير مرتبة
بحث ثنائيO(log n)مصفوفات مرتبة
ترتيب فقاعيO(n²)مصفوفات صغيرة جداً
ترتيب سريعO(n log n)أغلب الحالات

مثال: بحث خطي مقابل ثنائي

sad
# بحث خطي - O(n)
دالة بحث_خطي(مصفوفة، قيمة)
    لكل م في مدى(0، طول(مصفوفة) - 1)
        إذا (مصفوفة[م] == قيمة)
            ارجع م
        نهاية
    نهاية
    ارجع -1
نهاية

# بحث ثنائي - O(log n)
دالة بحث_ثنائي(مصفوفة، قيمة)
    متغير يسار = 0
    متغير يمين = طول(مصفوفة) - 1
    
    بينما (يسار <= يمين)
        متغير وسط = (يسار + يمين) / 2
        إذا (مصفوفة[وسط] == قيمة)
            ارجع وسط
        وإلا
            إذا (مصفوفة[وسط] < قيمة)
                يسار = وسط + 1
            وإلا
                يمين = وسط - 1
            نهاية
        نهاية
    نهاية
    ارجع -1
نهاية

تحسين الذاكرة

التخزين المؤقت (Memoization)

sad
دالة فيبوناتشي_بطيء(ن)
    إذا (ن <= 1)
        ارجع ن
    نهاية
    ارجع فيبوناتشي_بطيء(ن - 1) + فيبوناتشي_بطيء(ن - 2)
نهاية

# مع التخزين المؤقت
متغير ذاكرة = {}
دالة فيبوناتشي_سريع(ن)
    إذا (ن في ذاكرة)
        ارجع ذاكرة[ن]
    نهاية
    إذا (ن <= 1)
        ذاكرة[ن] = ن
    وإلا
        ذاكرة[ن] = فيبوناتشي_سريع(ن - 1) + فيبوناتشي_سريع(ن - 2)
    نهاية
    ارجع ذاكرة[ن]
نهاية

تجنب التكرار غير الضروري

sad
# سيء: حساب الطول في كل دورة
بينما (م < طول(مصفوفة))
    # ...
    م = م + 1
نهاية

# أفضل: حساب الطول مرة واحدة
متغير الطول = طول(مصفوفة)
بينما (م < الطول)
    # ...
    م = م + 1
نهاية

نصائح الأداء

نصائح عامة

  1. قس الأداء قبل التحسين — لا تحسّن بدون بيانات
  2. اختر الهيكل المناسب: الخريطة للبحث السريع، المصفوفة للترتيب
  3. استخدم التخزين المؤقت للعمليات المكررة المكلفة
  4. تجنب إنشاء كائنات غير ضرورية داخل الحلقات

تمرين

حسّن الدالة التالية لتعمل بشكل أسرع:

sad
دالة عد_تكرارات(مصفوفة، قيمة)
    متغير عداد = 0
    لكل عنصر في مصفوفة
        لكل عنصر2 في مصفوفة
            إذا (عنصر == قيمة و عنصر2 == قيمة)
                عداد = عداد + 1
            نهاية
        نهاية
    نهاية
    ارجع عداد
نهاية
الحل
sad
# O(n) بدلاً من O(n²)
دالة عد_تكرارات(مصفوفة، قيمة)
    متغير عداد = 0
    لكل عنصر في مصفوفة
        إذا (عنصر == قيمة)
            عداد = عداد + 1
        نهاية
    نهاية
    ارجع عداد
نهاية

مُرخَّص بموجب رخصة MIT