استخدام Python Timeit لتوقيت الكود الخاص بك
نشرت: 2023-01-17في هذا البرنامج التعليمي ، ستتعلم كيفية استخدام وظيفة timeit من وحدة timeit في Python. ستتعلم كيفية ضبط توقيت التعبيرات والوظائف البسيطة في بايثون.
يمكن أن يساعدك توقيت الكود في الحصول على تقدير لوقت تنفيذ جزء من التعليمات البرمجية وأيضًا تحديد أقسام الكود التي تحتاج إلى تحسين.
سنبدأ بتعلم بناء جملة دالة timeit
. وبعد ذلك سنقوم بتشفير الأمثلة لفهم كيفية استخدامها لكتل زمنية من التعليمات البرمجية والوظائف في وحدة Python الخاصة بك. هيا نبدأ.
كيفية استخدام وظيفة الوقت بيثون
تعد وحدة timeit
جزءًا من مكتبة Python القياسية ، ويمكنك استيرادها:
import timeit
الصيغة المستخدمة في استخدام وظيفة timeit
من وحدة timeit
كما هو موضح أدناه:
timeit.timeit(stmt, setup, number)
هنا:
-
stmt
هو جزء من الكود الذي سيتم قياس وقت تنفيذه. يمكنك تحديدها كسلسلة Python بسيطة أو سلسلة متعددة الأسطر ، أو تمرير اسم قابل للاستدعاء. - كما يوحي الاسم ، يشير
setup
إلى جزء الكود الذي يجب تشغيله مرة واحدة فقط ، غالبًا كشرط أساسي لتشغيلstmt
. على سبيل المثال ، افترض أنك تحسب وقت التنفيذ لإنشاء مصفوفة NumPy. في هذه الحالة ، استيرادnumpy
هو رمزsetup
والإنشاء الفعلي هو البيان المطلوب توقيته. - يشير
number
المعلمة إلى عدد مرات تشغيلstmt
. القيمة الافتراضيةnumber
هي 1 مليون (1000000) ، ولكن يمكنك أيضًا تعيين هذه المعلمة على أي قيمة أخرى من اختيارك.
الآن بعد أن تعلمنا بناء الجملة لاستخدام وظيفة timeit()
، فلنبدأ في ترميز بعض الأمثلة.
توقيت تعبيرات بايثون البسيطة
في هذا القسم ، سنحاول قياس وقت تنفيذ تعبيرات بايثون البسيطة باستخدام timeit.
ابدأ تشغيل Python REPL وقم بتشغيل أمثلة التعليمات البرمجية التالية. هنا ، نقوم بحساب وقت تنفيذ عمليات تقسيم الأسي والأرضية لـ 10000 و 100000 مرة.
لاحظ أننا نمرر في العبارة ليتم توقيتها كسلسلة 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
هو خيار سطر أوامر يشير إلى عدد مرات تشغيل الكود. هذا يعادل وسيطةnumber
في استدعاء دالة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
في سطر الأوامر ، يتم تعيين خيار repeat
r
على القيمة الافتراضية 5. وهذا يعني أن تنفيذ stmt
number
المرات المحدد يتكرر خمس مرات ، ويتم إرجاع أفضل أوقات التنفيذ.
تحليل طرق عكس الأوتار باستخدام timeit
عند العمل مع سلاسل Python ، قد ترغب في عكسها. الطريقتان الأكثر شيوعًا لعكس السلسلة هما كما يلي:
- استخدام تقطيع الخيوط
- استخدام الدالة
reversed()
وطريقةjoin()
عكس سلاسل Python باستخدام String Slicing
دعنا نتعرف على كيفية عمل تشريح السلسلة ، وكيف يمكنك استخدامها لعكس سلسلة Python. يؤدي استخدام صيغة some-string[start:stop]
إلى إرجاع شريحة من السلسلة تبدأ من start
الفهرس وتمتد حتى مؤشر stop-1
. لنأخذ مثالا.
ضع في اعتبارك السلسلة التالية "Python". طول السلسلة 6 وقائمة المؤشرات هي 0 ، 1 ، 2 حتى 5.
>>> string_1 = 'Python'
عندما تحدد قيم start
والإيقاف ، تحصل على شريحة سلسلة تمتد من start
إلى stop
stop-1
. لذلك ، string_1[1:4]
"yth".
>>> string_1 = 'Python' >>> string_1[1:4] 'yth'
عندما لا تحدد قيمة start
، يتم استخدام قيمة start
الافتراضية للصفر ، وتبدأ الشريحة عند الفهرس صفر وتمتد حتى stop - 1
.
هنا ، قيمة stop
هي 3 ، لذا تبدأ الشريحة من الفهرس 0 وترتفع إلى الفهرس 2.
>>> string_1[:3] 'Pyt'
عندما لا تقوم بتضمين فهرس stop
، ترى أن الشريحة تبدأ من فهرس start
(1) وتمتد حتى نهاية السلسلة.
>>> string_1[1:] 'ython'
يؤدي تجاهل قيمتي start
stop
إلى إرجاع شريحة من السلسلة بأكملها.
>>> string_1[::] 'Python'
لنقم بإنشاء شريحة بقيمة step
. اضبط قيم start
stop
step
على 1 و 5 و 2 على التوالي. نحصل على شريحة من السلسلة تبدأ من 1 تمتد حتى 4 (باستثناء نقطة النهاية 5) تحتوي على كل حرف ثانٍ .
>>> string_1[1:5:2] 'yh'
عندما تستخدم خطوة سالبة ، يمكنك الحصول على شريحة تبدأ من نهاية السلسلة. مع تعيين الخطوة على -2 ، string_1[5:2:-2]
الشريحة التالية:
>>> string_1[5:2:-2] 'nh'
لذلك للحصول على نسخة معكوسة من السلسلة ، نتخطى قيم start
stop
ونضبط الخطوة على -1 ، كما هو موضح:
>>> string_1[::-1] 'nohtyP'
باختصار:
string[::-1]
تعيد نسخة معكوسة من السلسلة.
عكس السلاسل باستخدام وظائف مضمنة وطرق السلاسل
ستعيد وظيفة reversed()
المضمنة في 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()
على المكرر العكسي باستخدام بناء الجملة: <sep>.join(reversed(some-string))
.
يُظهر مقتطف الشفرة أدناه بعض الأمثلة حيث يكون الفاصل واصلة ومسافة ، على التوالي.
>>> '-'.join(reversed(string1)) 'nohtyP' >>> ' '.join(reversed(string1)) 'nohty P'
هنا لا نريد أي فاصل. لذلك اضبط الفاصل على سلسلة فارغة للحصول على نسخة معكوسة من السلسلة:
>>> ''.join(reversed(string1)) 'nohtyP'
يؤدي استخدام
''.join(reversed(some-string))
إلى إرجاع نسخة معكوسة من السلسلة.
مقارنة أوقات التنفيذ باستخدام timeit
حتى الآن ، تعلمنا طريقتين لعكس سلاسل بايثون. لكن أي منهم أسرع؟ هيا نكتشف.
في مثال سابق حيث قمنا بضبط توقيت تعبيرات بايثون البسيطة ، لم يكن لدينا أي كود setup
. هنا ، نقوم بعكس سلسلة بايثون. أثناء تشغيل عملية عكس السلسلة لعدد المرات المحددة بواسطة number
، فإن رمز setup
هو تهيئة السلسلة التي سيتم تشغيلها مرة واحدة فقط.
>>> 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
بالنسبة إلى نفس عدد مرات التشغيل لعكس السلسلة المحددة ، يكون أسلوب تشريح السلسلة أسرع من استخدام طريقة join()
reversed()
.
توقيت وظائف بايثون باستخدام 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()
مع قائمة من السلاسل كوسيطة. بعد ذلك ، دعنا نحدد رمز الإعداد . هل يمكنك تخمين ما يجب أن يكون رمز setup
؟
لكي يتم تشغيل استدعاء الوظيفة بنجاح ، يجب أن يشتمل رمز الإعداد على ما يلي:
- تعريف الوظيفة
hasDigit()
- تهيئة قائمة السلاسل الوسيطة
دعنا نحدد كود الإعداد في سلسلة setup
، كما هو موضح أدناه:
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=...,setup=...,number=...)
. بدلاً من ذلك ، يمكنك تشغيل timeit في سطر الأوامر لوقت مقتطفات التعليمات البرمجية القصيرة.
كخطوة تالية ، يمكنك استكشاف كيفية استخدام حزم ملفات تعريف Python الأخرى مثل line-profiler و memprofiler لتوصيف الكود الخاص بك للوقت والذاكرة ، على التوالي.
بعد ذلك ، تعرف على كيفية حساب فرق التوقيت في بايثون.