الدرس الخامس

Lesson_5 slides

:مقاييس الاداء وتقنيات الامثلة

:الهدف
بمعالجة الصورة وبماان الكود خاصتك يتعامل مع عدد كبير من العمليات بالثانية , من الضروري ان لا يؤمن فقط الحل الصحيح وانما بالشكل الاسرع,ولذلك في هذا الفصل سنتعلم
ا.قياس اداء البرنامج
ا.بعض النصح لتحسين الاداء
ا.وسنرى هذه التوابع
cv2.getTickCount() , cv2.getTickFrequency
opencvبدون توابع
timeيقدم بايثون توابع
والمفيدة بقياس زمن التنفيذ , وموديول اخر (بروفايل)يساعدك للحصول على تقرير كامل عن الكود, مثل كم استغرق كل تابع بالتنفيذ , اما اذا كنت تستخدم
Ipython
كما في حالتنا , فهناك تسهيلات اكثر , كما سنتعرف على اهمها , للمزيد راجع التوثيق الخاص بكل منها

:Opencv قياس الاداء مع

cv2.getTickCount
يعطي عدد دورات الساعة التي مرت من حدث مرجعي للحظة المناداة
ولذلك اذا استعديته قبل وبعد تنفيذ تابع فسيعطي عدد دورات الساعة خلال عمله.
cv2.getTickFrequency()
يعطي تردد دورات الساعة, او عدد الدورات بالثانية , ولذلك لايجاد :زمن التنفيذ بالثواني عليك فعل التالي
In [3]:
import cv2
import numpy as np
e1 = cv2.getTickCount()
# your code execution

e2 = cv2.getTickCount()
time = (e2 - e1)/ cv2.getTickFrequency()
In [5]:
img1 = cv2.imread('Rene_Decart.jpg')
e1 = cv2.getTickCount()
for i in xrange(5,49,2):
    img1 = cv2.medianBlur(img1,i)
e2 = cv2.getTickCount()
t = (e2 - e1)/cv2.getTickFrequency()
print t
# Result I got is 0.521107655 seconds
0.669499675506
لذلك عملياً حاسوبي ابطأ :)ا

:ملاحظة

يمكنك القيام بنفس الامر باستخدام الموديول
time
بدلا من السابق ,حيث يتم اخذ الفرق ايضاً لمناداتين للتابع

: opencv الامثلة الافتراضية في

مؤمثلة OpenCV العديد من التوابع في
ولكنها تتضمن ايضاً شيفرات غير مؤمثلة ,ولذلك اذا كان نظامنا داعماً لهكذا طرق فيجب علينا استغلالهم (تقريبا معظم المعالجات الحديثة داعمة لها)وهي تكون مفعلة بالاصل عند اتنفيذ (افتراضياً)بالمناسبة
ولذلك يتم تنفيذ الكود المؤمثل
Optimized
في حال انه ممكن , والا الاخر ونستخدم
cv2.useOptimized()
لمعرفة هل الامثلة ممكنة , ام لا , ونستخدم
cv2.setUseOptimized()
:للتمكين او الغاء التمكين , والتالي كمثال
In [5]:
cv2.useOptimized()
Out[5]:
True
In [7]:
%timeit res = cv2.medianBlur(img1,49)
10 loops, best of 3: 29.7 ms per loop
In [12]:
cv2.setUseOptimized(False)
In [9]:
cv2.useOptimized()
Out[9]:
False
In [11]:
%timeit res = cv2.medianBlur(img1,49)
10 loops, best of 3: 61.8 ms per loop
وكما نرى , فان الترشيح الاوسطي المؤمثل ,اسرع بحوالي الضعف من الغير مؤمثل , ولو نظرت لبرنامجه لوجدت ان امثلته من نوع
SIMD
ولذلك يمكنك تمكين الامثلة باعلى برنامجك (تذكر الامثلة افتراضية)مبدئياً

: IPython قياس الاداء في

احياناً تحتاج قياس الاداء لعمليتين متشابهتين , و
IPython
يزودنا بامر سحري لذلك , وهو
%timeit
فهو يشغل البرنامج عدة مرات لمعرفة الزمن اللازم لها بدقة , وايضاً تتناسب هذه الطريقة مع التعليمات المفردة
مثلا هل تعرف اي من عمليات الجمع التالية افضل
هذا سنعرفه من خلال هذا الامر وبواجهة ايبايثون
In [13]:
x = 5
In [14]:
%timeit y=x**2
The slowest run took 10.41 times longer than the fastest. This could mean that an intermediate result is being cached 
1000000 loops, best of 3: 232 ns per loop
In [15]:
%timeit y=x*x
The slowest run took 7.27 times longer than the fastest. This could mean that an intermediate result is being cached 
1000000 loops, best of 3: 249 ns per loop
In [16]:
z = np.uint8([5])
In [17]:
%timeit y=z*z
The slowest run took 36.23 times longer than the fastest. This could mean that an intermediate result is being cached 
100000 loops, best of 3: 2.07 µs per loop
In [18]:
%timeit y=np.square(z)
The slowest run took 23.90 times longer than the fastest. This could mean that an intermediate result is being cached 
100000 loops, best of 3: 2.25 µs per loop
ومنه يمكنك الاستنتاج , مع تجاهل اخطاء الهاردوير , ان عملية الضرب
y = x*x
هي الاسرع بحوالي 20 مرة من انشاء المصفوفات في
Numpy
واذا اخذت بعين الحسبان ,انشاء المصفوفات فقد يصل لحوالي 100 مرة اسرع , جيد هه؟
Numpyوهذه ثغرة يتم العمل عليها في

:ملاحظة

عمليات الارقام القياسية في بايثون, اسرع من عمليات
Numpy
للارقام المفردة , ولذلك لتلك العمليات المتضمنة عددا او اثنين استخدم بايثون , فائدة
Numpy
:تكمن عندما يزداد حجم المصفوفة قليلا
وسنجرب الان مثالا اضافيا اخر , هذه المرة ,سنقارن اداء التابعين التاليين لنفس الصورة
cv2.countNonZeo() , np.count_nonzero()
In [9]:
%timeit z = cv2.countNonZero(img1)
10000 loops, best of 3: 37.6 µs per loop
In [10]:
%timeit z = np.count_nonzero(img1)
1000 loops, best of 3: 678 µs per loop
cv2 نلاحظ ان توابع
np اسرع ب 25 مرة من توابع

: ملاحظة

عادة توابع
opencv
اسرع من توابع
Numpy
ولذلك لاجل نفس العملية استعمل الاول , ولكن هناك استثناءات , مثلاً عند تعامل الثانية مع العرض بدلاً من النسخ.

: تقنيات امثلة الاداء

الشيء الرئيسي هنا انه عليك اولاً ايجاد تطبيق الخوارزمية بشكل بسيط ثم توضيح ادائها بعد عملها الصحيح , ثم ايجاد العراقيل فيه , وامثلته.
تجنب استخدام الحلقات ببايثون , وخصوصاً الحلقات الثنائية والثلاثية نظراً لبطئها.
اجعل الخوارزمية باوسع شكل للاشعة لأن العمليات في كلا المكتبتين مؤمثلة للاشعة .
استفد من المتغيرات المعرفة مسبقاً
لا تنسخ المصفوفات , مالم تحتاج ذلك ,حاول استخدام العرض بدلاً من ذلك ,لان نسخها عملية مكلفة
وحتى بعد كل ذلك , اذا بقي برنامجك بطيئاً او لا يحتمل التعديل , يمكنك التسريع باستخدام مكتبات ك
cython
لجعله اسرع
In [ ]:
 

ليست هناك تعليقات:

إرسال تعليق