ما هي الطرق التي تؤدي بها استثناءات C++ إلى إبطاء التعليمات البرمجية في حالة عدم وجود استثناءات؟

StackOverflow https://stackoverflow.com/questions/1897940

  •  19-09-2019
  •  | 
  •  

سؤال

لقد قرأت أن هناك بعض الحمل الزائد لاستخدام استثناءات C++ لمعالجة الاستثناءات بدلاً من التحقق من قيم الإرجاع، على سبيل المثال.أنا أتحدث فقط عن النفقات العامة التي يتم تكبدها عند عدم طرح أي استثناء.أفترض أيضًا أنك ستحتاج إلى تنفيذ التعليمات البرمجية التي تتحقق بالفعل من قيمة الإرجاع وتفعل الشيء المناسب، مهما كان ما يعادل ما ستفعله كتلة الالتقاط.كما أنه ليس من العدل أيضًا مقارنة التعليمات البرمجية التي تطرح كائنات استثناء تحتوي على 45 متغير حالة بداخلها مع التعليمات البرمجية التي تُرجع عددًا صحيحًا سالبًا لكل خطأ.

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

هل كانت مفيدة؟

المحلول

هناك تكلفة مرتبطة باستثناء التعامل معها بعض منصات ومع بعض المترجمون.

وهي Namely، ستسجيل Visual Studio، عند بناء هدف 32 بت، معالجا في كل وظيفة تحتوي على متغيرات محلية مع المدمر غير التافهة. أساسا، إنه يضع try/finally معالج.

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

نصائح أخرى

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

أود أن ينصح بعدم القلق بشأن هذا الأمر، واستخدام ملف تعريف بدلا من ذلك لتحسين التعليمات البرمجية عند الحاجة.

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

بالطبع، ستحتاج إلى قياس الأداء لمتطلباتك الخاصة للتأكد.

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

لكن ليس لديك الكثير من الاختيار في الوقت الحاضر. حاول القيام بتعطيل الاستثناءات في مشروعك، وتأكد من أن جميع الكود والمكتبات التابعة يمكن أن تجميعها وتشغيلها دون.

هل يعملون مع استثناءات المعوقين؟

دعونا نفترض أنهم يفعلون! ثم معيار بعض الحالات، ولكن لاحظ أنه يجب عليك تعيين رمز التبديل "تعطيل استثناءات". بدون هذا التبديل، لا يزال لديك النفقات العامة - حتى لو لم يطرح الكود استثناءات.

النفقات العامة فقط هي ~ 6 تعليمات تضيف 2 SEH في بداية الوظيفة واتركها في النهاية. بغض النظر عن عدد المحاولة / المصيد لديك في مؤشر ترابط هو نفسه دائما.

أيضا ما هذا حول المتغيرات المحلية؟ أسمع الناس يشكون دائما منهم عند استخدام TRY / CATCH. أنا لا أفهم ذلك، لأن النفض في النهاية سيتم استدعاؤها على أي حال. كما يجب أن لا تسمح باستثناء المزيد من المكالمات 1-3.

لقد أخذت رمز اختبار Chip Uni وقمت بتوسيعه قليلاً.لقد قمت بتقسيم الكود إلى ملفين مصدريين (أحدهما به استثناءات؛واحد بدون).لقد قمت بتشغيل كل معيار 1000 مرة، واستخدمت clock_gettime() مع CLOCK_REALTIME لتسجيل أوقات البداية والنهاية لكل تكرار.ثم قمت بحساب المتوسط ​​والتباين للبيانات.لقد أجريت هذا الاختبار باستخدام إصدارات 64 بت من g++ 5.2.0 و clang++ 3.7.0 على جهاز Intel Core i7 مزود بذاكرة وصول عشوائي (RAM) سعة 16 جيجابايت يعمل بنظام ArchLinux مع kernel 4.2.5-1-ARCH.يمكنك العثور على الكود الموسع والنتائج الكاملة هنا.

ز++

لا استثناءات
  • متوسط:30,022,994 نانو ثانية
  • الانحراف المعياري:1.25327e+06 نانو ثانية
الاستثناءات
  • متوسط:30,025,642 نانو ثانية
  • الانحراف المعياري:1.83422e+06 نانو ثانية

clang++

لا استثناءات
  • متوسط:20,954,657 نانو ثانية
  • الانحراف المعياري:426,662 نانو ثانية
الاستثناءات
  • متوسط:23,916,638 نانو ثانية
  • الانحراف المعياري:1.72583e+06 نانو ثانية

لا تؤدي استثناءات C++ إلا إلى عقوبة أداء غير تافهة مع clang++، وحتى تلك العقوبة تبلغ 14% فقط.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top