" حذار من المعطيات التي تتعامل بها "
هذه بعض السطور التي غالبا ما نجدها ضمن شيفرة التي تظهر رسوما متحركة على الشاشة، مثلا:
كود :
[COLOR=Blue]Var X, Y, Angle, Hypot : Smallint;
for Angle := 0 to 360 do begin
X := Round( cos(DegToRad(Angle)) * Hypot );
Y := Round( sin(DegToRad(Angle)) * Hypot );
end;
[/COLOR]أولا، الوحدة Math تمكننا من استعمال الإجراء ()SinCos الذي هو أسرع مرتين من مناداة ()Sin متبوعة بـ ()Cos:
كود :
[COLOR=Blue]Var X, Y, Angle, Hypot : Smallint
Sinus, Cosin : Extended;
for Angle := 0 to 360 do begin
SinCos(DegToRad(Angle) ,Sinus, Cosin);
X := Round( Cosin * Hypot );
Y := Round( Sinus * Hypot );
end;
[/COLOR]DegToRad أوضح وأفضل لقراءة الشيفرة، لكنها تأخذ الكثير من الوقت للتنفيذ. ننزعها و نقوم بالتالي:
كود :
[COLOR=Blue]for Angle := 0 to 360 do begin
SinCos(Angle*0.0174532925199433 ,Sinus, Cosin);
X := Round( Cosin * Hypot );
Y := Round( Sinus * Hypot );
end;[/COLOR]المعطيات المخبأة:
سرعة الإجراء ()SinCos ليس بسرعة استعمال الجدول. إن تقنية تخبئة المعلومات تعتمد على حفظ - بصورة نظامية - القيَم المستعملة بكثرة في الذاكرة. هنا سنخزن القيَم المثلثية في الجدول:
كود :
[COLOR=Blue]Var //متغيرات عامة
MonCos : array[0..360] of Extended; // جدول مخبأ
MonSin : array[0..360] of Extended; // جدول مخبأ
procedure TForm1.FormCreate(Sender: TObject);
var Angle : Integer;
Sinus, Cosin : Extended;
begin
for Angle := 0 to 360 do begin
SinCos(Angle*0.0174532925199433 ,Sinus, Cosin);
MonSin[ Angle ] := Sinus; // إنشاء جدول مخبأ
MonCos[ Angle ] := Cosin;
end;
...
for Angle := 0 to 360 do begin
X := Round( MonCos[ Angle ] * Hypot );
Y := Round( MonSin[ Angle ] * Hypot );
end;
[/COLOR]وحدة المعالجة المركزية محسَّنة من أجل 32 بيت:
بدون شك لاحظت أننا عملنا بـ SmallInt في حلقة الحساب. هذا مبرر لأنها كافية لحساب إحداثيات الشاشة. في حين، وحدة المعالجة المركزية تعمل براحة كبيرة عندما تتعامل مع Integer. التعديلات بسيطة:
كود :
[COLOR=Blue]Var X, Y, Angle, Hypot : Integer;
Sinus, Cosin : Extended;[/COLOR]ضبط الزائد عن الحاجة لإجراءات النظام:
نعم في الحقيقة نحن نعمل على الشاشة.
إنها قيمة مثلثية من Extended أي ( 15رقما بعد الفاصلة) تضبط عملية إنزال رجل على القمر، بالنسبة لشاشتي 'm….' لست بحاجة لمثل هذه الدقة. سنقلل من دقة جداول المعطيات المثلثية المخبأة.
و مثلما رأينا أن وحدة معالجة المعطيات تحبذ 32 بيت. إذن و في نفس السياق نحول extendeds إلى Integers.
و في طريقنا نحذف Round، إجراء تابع للنظام مكلف أيضا.
كود :
[COLOR=Blue]Var // متغيرات عامة
MonCosInt : array[0..360] of Integer; // جدول مخبأ
MonSinInt : array[0..360] of Integer; // جدول مخبأ
procedure TForm1.FormCreate(Sender: TObject);
var Angle : Integer;
Sinus, Cosin : Extended;
begin
for Angle := 0 to 360 do begin
SinCos(Angle*0.0174532925199433 ,Sinus, Cosin);
MonSinInt[ Angle ] := Round( Sinus * 1000 );
MonCosInt[ Angle ] := Round( Cosin * 1000 );
end;
...
for Angle := 0 to 360 do begin
X := MonCosInt[ Angle ] * Hypot div 1000;
Y := MonSinInt [ Angle ] * Hypot div 1000;
end;
[/COLOR]أحيانا، مع هذه التقنية، سنحصل على أخطاء صغيرة بخصوص الإحداثيات بسبب الدوران إلى أسفل Div. لكن بالنسبة للرسوم متحركة على الشاشة ستمر بشكل خفي وفي كل الحالات نحن الكاسبون.
تفطَّن لكل شيء:
في رأيكم، ما المزعج في الشيفرة التالية:
كود :
[COLOR=Blue]Hypothenuse1 := Sqrt( Sqr(CoteA1) + Sqr(CoteB1) );
Hypothenuse2 := Sqrt( Sqr(CoteA2) + Sqr(CoteB2) );
if Hypothenuse1 < Hypothenuse2 then {افعل الأتي}; [/COLOR]CoteA1 + CoteB1 < CoteA2 + CoteB2
يمكننا أن نتجنب تكلفة ()Sqrt و ()Sqr عبر التالي:
كود :
[color=Blue]if CoteA1 + CoteB1 < CoteA2 + CoteB2 then {افعل الأتي};[/color]
