تكتيكات لتحقيق أقصى سرعة لتنفيذ الشيفرة [مترجم]
#4
تحقق من الحلقات

ضع الاختبارات خارج الحلقات:

من السهل الاهتداء إلى الاختبارات التي لا تُعدَّل داخل الحلقات:

for i := 0 to High(TableTest) do begin
if Choix = 0 then TableTest[i] := TableTest[i] + 1
else TableTest[i] := TableTest[i] - 1;
end

و هي نفسها محسنة:
if Choix = 0 then
for i := 0 to High(TableTest) do TableTest[i] := TableTest[i] + 1
else for i := 0 to High(TableTest) do TableTest[i] := TableTest[i] - 1
نسبة الأداء = 1.35 : 1

التحكم في الحلقات:

هذه التقنية تشبه المثال الأول في هذه المقالة أين سيَّرنا بشكل كامل الحلقة من 10 تكرارات. تطبيقيا، لا يمكن تحقيقه من أجل عدد كبير من العناصر أو عندما تكون هذه الأخيرة غير معلومة. و مع ذلك يمكننا أن نحقق هذه التقنية. هذه حلقة عادية:
i:=0;
while i < High(TableTest) do begin
TableTest[i]:= 0;
Inc(i);
end
و مثال لنفس الحلقة معدلة جزئيا:
i:=0;
while i < High(TableTest)-3 do begin
TableTest[i]:= 0;
TableTest[i+1]:= 0;
TableTest[i+2]:= 0;
TableTest[i+3]:= 0;
inc(i,4);
end

{نضبط الحالات الأخيرة}
if i = High(TableTest)-1 then TableTest[High(TableTest)-1] := 0;
if i = High(TableTest)-2 then TableTest[High(TableTest)-2] := 0;
if i = High(TableTest)-3 then TableTest[High(TableTest)-3] := 0
نسبة الأداء = 1.4 : 1

لكن هذه التقنية لا أحبذها. أولا وجدتها فظيعة. وأيضا، يجب فعلا اختبار زيادة الأداء في كل حالة لأنه يمكن أن تتغير حسب العمليات المنفذة. مجمِّع دلفي يقوم عامة بعمل أحسن من هذا الترقيع. اختبرها ولا تستعملها إلا إذا كانت سرعة التنفيذ مرتفعة.

القيمة الحارسة:

مثال عن حلقة بحث تحتوي على اختبار مركب:
NegativeFound := False;
i := 0;
while (not NegativeFound) and (i < High(TableTest)) do begin
if TableTest[i] < 0 then NegativeFound := true;
inc(i);
end
في هذه الشيفرة، مع انه نخرج في الحين، غير أن كل تكرار يختبر (not NegativeFound) و (i < High(TableTest)).
الاختبار TableTest[i] < 0 وظيفته أن يحدد لنا إذا ما كانت القيمة السالبة قد وجدت. الحلقة، إذاً، تنفِّذ 3 اختبارات في كل تكرار.

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

هنا، سنعطي قيمة سالبة إلى آخر عنصر بالجدول. إذا لم نجد القيمة السالبة قبل تلك التي وضعناها في الأخير، نعرف أن القيمة التي نبحث عنها لا توجد في الجدول.

بعض سطور من الشيفرة توضح أحسن من شرح طويل:
TableTest[High(TableTest)] := -1;
كود :
[color=SeaGreen]//القيمة الحارسة[/color] NegativeFound := false; I := 0; while not TableTest[i] < 0 do inc(i) ; [COLOR="SeaGreen"]// نخرج { و نتحقق إذا ما قد وجدت القيمة}[/COLOR] if i < High(TableTest) then NegativeFound := true[/align][/COLOR]
[color=Red]نسبة الأداء = 1.7 : 1

ضع الحلقة الأكثر نشاطا في الداخل:

عندما تكون الحلقات مركبة، فكر في أي الحلقات ستضعها خارجا وأيها ستضعها في الداخل. المثال التالي قابل للتحسين:
[align=left]for Col := 0 to 999 do
for Ligne := 0 to 1 do Total := Total + MaTable[ Col, Ligne ];

الحلقة الخارجية تتكرر 1000 مرة. الحلقة الداخلية تتكرر 2 × 1000 = 2000 مرة. إذا لدينا المجموع 3000 تكرار.
نعكس الحلقات:
for Ligne := 0 to 1 do
for Col := 0 to 999 do Total := Total + MaTable[ Col, Ligne ]
نسبة الأداء = 1.9 : 1

في الشيفرة المحسنة الحلقة الخارجية تنفذ مرتين. الحلقة الداخلية تنفذ 2 × 1000 = 2000 مرة. إذا لدينا المجموع 2002 تكرار.
الرد


الردود في هذا الموضوع
تكتيكات لتحقيق أقصى سرعة لتنفيذ الشيفرة [مترجم] - بواسطة merouane - 25-03-2008, 02:13 PM

التنقل السريع :


يقوم بقرائة الموضوع: بالاضافة الى ( 1 ) ضيف كريم