الشبكة العربية لمطوري الألعاب

موهوب  16mofed84 مشاركة 1

السلام عليكم
اني احذر الجميع من استخدام try-catch
لعدم الاكتراث للخطأ فهذا يسبب ضعف الأداء بشكل كبير و لعلاج المشكله يتبع الاتي (مثال):


try
{
    _transforms[3] = newTransform;
}
catch// الخطأ المممكن هو ان المصوفة لا تحتوي عنصر ثالث
{
    //...
}

الحل:

if(_transforms.Length > 3)
{
    _transforms[3] = newTransform;
}
else
{
    //....
}

و ايضا ... من الاشياء المضعفة للاداء :...
http://origin-developer.nvidia.com/docs/IO/8230/BatchBatchBatch.pdf?q=docs/IO/8230/BatchBatchBatch.pdf
و يوجد مئات الطرق لتسريع الاداء و لا يمكن ذكرها ..تعتمد على نوع المشكلة
و شكرا ,,

مبتدئ  إياد الجوابرة مشاركة 2

السلام عليكم
بالنسبة لموضوع معالجة الاستثناءات والأداء، فإني أعتقد أن هناك بعض الالتباس؛
للنظر في هذا الموضوع يجب التمييز بين الحالات التالية:
أولا: ما هي طريقة المترجم في معالجة الاستثناء، وهنا (على حد علمي المتواضع)
إما أن يقوم المترجم ببناء جدول يبحث فيه عن أقرب عبارة catch مطابقة لما تم عمل throw له
أو عند دخول كل مجل رؤية (scope) يقوم بوضع كل عبارة catch يصادفها في المكدس، وعندما يقوم أحدهم برمي خطأ ما، يقوم التنفيذ إخراج عبارات ال catch من المكدس حتى يصل للعبارة المناسبة.
وثانيا: هل الرماز المكتوب يقوم بتوليد الأخطاء وهل إحتمال ذلك كبير؟
ففي الحالة الأولى ليست هناك كلفة زائدة في حال عدم حدوث خطأ، وفي حال حدوث خطأ يتطلب الأمر بحثا في الجدول.
وفي الحالة الثانيا هناك كلفة زائدة في التنفيذ حتى في حال عدم حدوث أخطاء، إلا أن كلفة البحث هنا هي عبارة عن إخراج من المكدس فهي شبه معدومة.

بصراحة لا أعرف الطريقة آلية عمل مترجم c++ بالنسبة لمعالجة الاستثناءات، ولا أعلم إن كانت مختلفة من مترجم لآخر،لكن؛ بالنسبة للغات الافتراضية (جافا و سي شارب وأي سكريبت) فإن المترجم يقوم بوضع اختبارات عند كل عملية قد ترمي خطأ وقت التنفيذمثلا عند كل وصول لعنصر من مصفوفة





str[i] = a


فإن المترجم يقوم بوضع اختبار كالتالي:




if (i < str.length)
str[i] = a
else
throw new ArrayIndexOutOfBoundsException();


ولذلك إذا كان الرماز حرج ويتطلب سرعة في التنفيذ يجب التحايل على المترجم، مثلا في جافا المرور على عناصر مصفوفة يكون كالتالي: (لاحظ أنi++ اسرع من ++i)



for (int i = 0; i < array.length; ++i)
System.out.println(array[i]);



وبما أن المترجم يقوم بالاختبار تلقائيا وفي حال الخروج عن عدد عناصر المصفوفة يقوم برمي خطأ فإن الأجدى بنا أن نكتب:




try
{
for (; ; )
    System.out.println(array[++i]);
}
catch(ArrayIndexOutOfBoundsException e)
{
}


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

خبير مدير وسام البهنسي مشاركة 3

الاستثناءات طريقة جيدة للحصول على كود نظيف، لكنها فعلاً تأتي بمقابل بعض البطء في الأداء. لذلك يفضل استخدامها بحذر في الإجراءات والأماكن التي تعمل ضمن حلقات ذات تكرار عالي أو تستدعى بكثرة.
 
من الأماكن المثالية لاستخدام الاستثناءات عمليات فتح الملفات والتعامل مع القرص الصلب، أو إنشاء الكائنات. هذا الصنف من العمليات يمكنه دائماً الاعتماد على الاستثناءات دون الخوف من التأثير على الأداء (وذلك بسبب الطبيعة البطيئة لهذه العمليات أصلاً). أما العمليات السريعة والمكررة غالباً مثل الوصول إلى عناصر مصفوفة فلها أسلوب آخر في التعامل، بحيث نستفيد من مزايا الاستثناءات دون خسارة أداء.
 
من هذه الأساليب حصر إطلاق الاستثناءات في نسخة التنقيح (Debug Version) فقط من البرنامج، والتخلص منها كلياً في نسخة الطرح (Release Version).
 
كمبرمج يستخدم إجراءات ووظائف قد ترمي استثناءات، عليك التقرير إن كان سيناريو الفشل يجب أن يكون متوقعاً في برنامجك أم لا.. مثلاً، نريد فتح ملف باسم معين. هذه العملية لها الكثير من العوامل التي قد تتسبب بفشلها، كعدم وجود الملف أو كونه مفتوحاً من قبل برنامج آخر أو أو أو... المهم أن احتمالات الفشل قائمة. هنا لا تريد للبرنامج أن ينهار بمجرد وقوع أحد هذه الحالات "الاستثنائية"، وإنما أنت تتوقع حدوثها ولديك طريق في البرنامج للتعامل مع هذه الحالات (مثلاً إظهار رسائل خطأ للمستخدم).
 
بالمقابل، هناك أماكن لا تتوقع أن يحصل بها خطأ، مثل الوصول إلى عنصر خارج حدود مصفوفة. هنا نقرر أن هذا الخطأ يجب أن يتم إصلاحه وليس تركه يحدث، فهو خطأ المبرمج وليس خطأ المستخدم أو خطأ نظام التشغيل كي نتعامل معه. في هذه الحالات لا يجب أن نحيط الكود هذا بعبارة try و catch، لأن هذا أقرب لما تفعله النعامة ☺  الصحيح في مثل هذه الحالات هو تجريب البرنامج في نمط التنقيح والوقوف عند الخطأ حال حدوثه. فكما نعرف، الاستثناء المرمي الذي لم يتم تلقفه من قبل الكود، سيتم تلقفه من قبل نظام التشغيل وسيتم إغلاق البرنامج بالقوة غالباً. الفكرة هنا أننا في لحظتها سنعرف كل المعلومات المساعدة في إصلاح الخطأ مثل السطر الذي تسبب في الخطأ، ومكدس نداء الإجراءات، وقيم المتغيرات الحالية.

وسام البهنسي
مبرمج في إنفيديا وإنفريمز