استخدام Python Timeit لتوقيت الكود الخاص بك

في هذا البرنامج التعليمي ، ستتعلم كيفية استخدام وظيفة timeit من وحدة timeit في Python. ستتعلم كيفية ضبط توقيت التعبيرات والوظائف البسيطة في بايثون.

يمكن أن يساعدك توقيت الكود في الحصول على تقدير لوقت تنفيذ جزء من التعليمات البرمجية وأيضًا تحديد أقسام الكود التي تحتاج إلى تحسين.

سنبدأ بتعلم بناء جملة دالة الوقت بيثون. وبعد ذلك سنقوم بتشفير الأمثلة لفهم كيفية استخدامها لكتل ​​زمنية من التعليمات البرمجية والوظائف في وحدة Python الخاصة بك. هيا نبدأ.

كيفية استخدام وظيفة الوقت بيثون

تعد وحدة timeit جزءًا من مكتبة Python القياسية ، ويمكنك استيرادها:

import timeit

الصيغة المستخدمة في استخدام وظيفة timeit من وحدة timeit كما هو موضح أدناه:

timeit.timeit(stmt, setup, number)

هنا:

  • stmt هو جزء من الكود الذي سيتم قياس وقت تنفيذه. يمكنك تحديدها كسلسلة Python بسيطة أو سلسلة متعددة الأسطر ، أو تمرير اسم قابل للاستدعاء.
  • كما يوحي الاسم ، يشير الإعداد إلى جزء الكود الذي يجب تشغيله مرة واحدة فقط ، غالبًا كشرط أساسي لتشغيل stmt. على سبيل المثال ، افترض أنك تحسب وقت التنفيذ لإنشاء مصفوفة NumPy. في هذه الحالة ، استيراد numpy هو رمز الإعداد والإنشاء الفعلي هو البيان المطلوب توقيته.
  • يشير رقم المعلمة إلى عدد مرات تشغيل stmt. القيمة الافتراضية للرقم هي 1 مليون (1000000) ، ولكن يمكنك أيضًا تعيين هذه المعلمة على أي قيمة أخرى من اختيارك.

الآن بعد أن تعلمنا بناء الجملة لاستخدام وظيفة timeit () ، فلنبدأ في ترميز بعض الأمثلة.

توقيت تعبيرات بايثون البسيطة

في هذا القسم ، سنحاول قياس وقت تنفيذ تعبيرات بايثون البسيطة باستخدام timeit.

ابدأ تشغيل Python REPL وقم بتشغيل أمثلة التعليمات البرمجية التالية. هنا ، نقوم بحساب وقت تنفيذ عمليات تقسيم الأسي والأرضية لـ 10000 و 100000 مرة.

  قبل نظام Mac OS X: ما هو NeXTSTEP ، ولماذا أحب الناس ذلك؟

لاحظ أننا نمرر في العبارة ليتم توقيتها كسلسلة Python ونستخدم فاصلة منقوطة لفصل التعبيرات المختلفة في العبارة.

>>> import timeit
>>> timeit.timeit('3**4;3//4',number=10000)
0.0004020999999738706

>>> timeit.timeit('3**4;3//4',number=100000)
0.0013780000000451764

تشغيل Python timeit في سطر الأوامر

يمكنك أيضًا استخدام timeit في سطر الأوامر. فيما يلي مكافئ سطر الأوامر لاستدعاء دالة timeit:

$ python-m timeit -n [number] -s [setup] [stmt]
  • يمثل python -m timeit أننا نقوم بتشغيل timeit كوحدة نمطية رئيسية.
  • n هو خيار سطر أوامر يشير إلى عدد مرات تشغيل الكود. هذا يعادل وسيطة الرقم في استدعاء دالة timeit ().
  • يمكنك استخدام الخيار -s لتحديد كود الإعداد.

هنا ، نعيد كتابة المثال السابق باستخدام مكافئ سطر الأوامر:

$ python -m timeit -n 100000 '3**4;3//4'
100000 loops, best of 5: 35.8 nsec per loop

في هذا المثال ، نحسب وقت تنفيذ وظيفة len () المدمجة. تهيئة السلسلة هي رمز الإعداد الذي يتم تمريره باستخدام الخيار s.

$ python -m timeit -n 100000 -s "string_1 = 'coding'" 'len(string_1)'
100000 loops, best of 5: 239 nsec per loop

في الإخراج ، لاحظ أننا نحصل على وقت التنفيذ لأفضل 5 أشواط. ماذا يعني هذا؟ عند تشغيل timeit في سطر الأوامر ، يتم تعيين خيار التكرار r على القيمة الافتراضية 5. وهذا يعني أن تنفيذ stmt لعدد المرات المحدد يتكرر خمس مرات ، ويتم إرجاع أفضل أوقات التنفيذ.

تحليل طرق عكس الأوتار باستخدام timeit

عند العمل مع سلاسل Python ، قد ترغب في عكسها. الطريقتان الأكثر شيوعًا لعكس السلسلة هما كما يلي:

  • استخدام تقطيع الخيوط
  • استخدام الدالة المعكوسة () وطريقة الانضمام ()

عكس سلاسل Python باستخدام String Slicing

دعنا نتعرف على كيفية عمل تشريح السلسلة ، وكيف يمكنك استخدامها لعكس سلسلة Python. استخدام بناء الجملة بعض السلاسل[start:stop] تُرجع شريحة من السلسلة تبدأ عند بداية الفهرس وتمتد حتى نقطة توقف الفهرس -1. لنأخذ مثالا.

ضع في اعتبارك السلسلة التالية “Python”. طول السلسلة 6 وقائمة المؤشرات هي 0 ، 1 ، 2 حتى 5.

>>> string_1 = 'Python'

عندما تحدد قيم البداية والإيقاف ، تحصل على شريحة سلسلة تمتد من البداية إلى الإيقاف -1. لذلك ، string_1[1:4] إرجاع “yth”.

>>> string_1 = 'Python'
>>> string_1[1:4]
'yth'

عندما لا تحدد قيمة البداية ، يتم استخدام قيمة البداية الافتراضية للصفر ، وتبدأ الشريحة عند الفهرس صفر وتمتد حتى التوقف – 1.

  مشغل الوسائط مع مجموعة واسعة من ملحقات الطرف الثالث

هنا ، قيمة الإيقاف هي 3 ، لذا تبدأ الشريحة من الفهرس 0 وترتفع إلى الفهرس 2.

>>> string_1[:3]
'Pyt'

عندما لا تقوم بتضمين فهرس الإيقاف ، ترى أن الشريحة تبدأ من فهرس البداية (1) وتمتد حتى نهاية السلسلة.

>>> string_1[1:]
'ython'

يؤدي تجاهل قيمتي البداية والإيقاف إلى إرجاع شريحة من السلسلة بأكملها.

>>> string_1[::]
'Python'

لنقم بإنشاء شريحة بقيمة الخطوة. اضبط قيم البدء والإيقاف والخطوة على 1 و 5 و 2 على التوالي. نحصل على شريحة من السلسلة تبدأ من 1 تمتد حتى 4 (باستثناء نقطة النهاية 5) تحتوي على كل حرف ثانٍ.

>>> string_1[1:5:2]
'yh'

عندما تستخدم خطوة سالبة ، يمكنك الحصول على شريحة تبدأ من نهاية السلسلة. مع تعيين الخطوة على -2 ، سلسلة_1[5:2:-2] يعطي الشريحة التالية:

>>> string_1[5:2:-2]
'nh'

لذلك للحصول على نسخة معكوسة من السلسلة ، نتخطى قيم البداية والإيقاف ونضبط الخطوة على -1 ، كما هو موضح:

>>> string_1[::-1]
'nohtyP'

باختصار: سلسلة[::-1] إرجاع نسخة معكوسة من السلسلة.

عكس السلاسل باستخدام وظائف مضمنة وطرق السلاسل

ستعيد وظيفة عكس () المضمنة في Python مكررًا عكسيًا على عناصر السلسلة.

>>> string_1 = 'Python'
>>> reversed(string_1)
<reversed object at 0x00BEAF70>

لذا يمكنك إجراء حلقة عبر المكرر العكسي باستخدام حلقة for:

for char in reversed(string_1):
    print(char)

والوصول إلى عناصر السلسلة بالترتيب العكسي.

# Output
n
o
h
t
y
P

بعد ذلك ، يمكنك استدعاء طريقة الانضمام () على المكرر العكسي باستخدام بناء الجملة: .join (معكوس (بعض السلسلة)).

يُظهر مقتطف الشفرة أدناه بعض الأمثلة حيث يكون الفاصل واصلة ومسافة ، على التوالي.

>>> '-'.join(reversed(string1))
'n-o-h-t-y-P'
>>> ' '.join(reversed(string1))
'n o h t y P'

هنا لا نريد أي فاصل. لذلك اضبط الفاصل على سلسلة فارغة للحصول على نسخة معكوسة من السلسلة:

>>> ''.join(reversed(string1))
'nohtyP'

يؤدي استخدام ”.join (معكوس (بعض السلاسل)) إلى إرجاع نسخة معكوسة من السلسلة.

مقارنة أوقات التنفيذ باستخدام timeit

حتى الآن ، تعلمنا طريقتين لعكس سلاسل بايثون. لكن أي منهم أسرع؟ هيا نكتشف.

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

>>> import timeit
>>> timeit.timeit(stmt="string_1[::-1]", setup = "string_1 = 'Python'", number = 100000)
0.04951830000001678
>>> timeit.timeit(stmt = "''.join(reversed(string_1))", setup = "string_1 = 'Python'", number = 100000)
0.12858760000000302

بالنسبة إلى نفس عدد مرات التشغيل لعكس السلسلة المحددة ، يكون أسلوب تشريح السلسلة أسرع من استخدام طريقة الانضمام () والوظيفة العكسية ().

  أفضل 10 قاذفات للأندرويد

توقيت وظائف بايثون باستخدام timeit

في هذا القسم ، دعنا نتعلم كيفية توقيت وظائف Python باستخدام وظيفة timeit. بالنظر إلى قائمة السلاسل ، تُرجع الدالة التالية hasDigit قائمة السلاسل التي تحتوي على رقم واحد على الأقل.

def hasDigit(somelist):
     str_with_digit = []
     for string in somelist:
         check_char = [char.isdigit() for char in string]
         if any(check_char):
            str_with_digit.append(string)
     return str_with_digit

نود الآن قياس وقت تنفيذ دالة بايثون hasDigit () باستخدام timeit.

دعونا أولاً نحدد العبارة المراد توقيتها (stmt). إنه استدعاء الوظيفة hasDigit () مع قائمة من السلاسل كوسيطة. بعد ذلك ، دعنا نحدد رمز الإعداد. هل يمكنك تخمين ما يجب أن يكون رمز الإعداد؟

لكي يتم تشغيل استدعاء الوظيفة بنجاح ، يجب أن يشتمل رمز الإعداد على ما يلي:

  • تعريف الوظيفة hasDigit ()
  • تهيئة قائمة السلاسل الوسيطة

دعنا نحدد كود الإعداد في سلسلة الإعداد ، كما هو موضح أدناه:

setup = """
def hasDigit(somelist):
    str_with_digit = []
    for string in somelist:
      check_char = [char.isdigit() for char in string]
      if any(check_char):
        str_with_digit.append(string)
    return str_with_digit
thislist=['puffin3','7frost','blue']
     """

بعد ذلك ، يمكننا استخدام وظيفة timeit والحصول على وقت تنفيذ وظيفة hasDigit () لـ 100000 عملية تشغيل.

import timeit
timeit.timeit('hasDigit(thislist)',setup=setup,number=100000)
# Output
0.2810094920000097

استنتاج

لقد تعلمت كيفية استخدام وظيفة الوقت في بايثون لتعبيرات الوقت والوظائف وغيرها من العناصر القابلة للاستدعاء. يمكن أن يساعدك هذا في قياس التعليمات البرمجية الخاصة بك ، ومقارنة أوقات تنفيذ عمليات التنفيذ المختلفة لنفس الوظيفة ، والمزيد.

دعنا نراجع ما تعلمناه في هذا البرنامج التعليمي. يمكنك استخدام الدالة timeit () مع بناء الجملة timeit.timeit (stmt =… ، الإعداد =… ، الرقم =…). بدلاً من ذلك ، يمكنك تشغيل timeit في سطر الأوامر لوقت مقتطفات التعليمات البرمجية القصيرة.

كخطوة تالية ، يمكنك استكشاف كيفية استخدام حزم ملفات تعريف Python الأخرى مثل line-profiler و memprofiler لتوصيف الكود الخاص بك للوقت والذاكرة ، على التوالي.

بعد ذلك ، تعرف على كيفية حساب فرق التوقيت في بايثون.