geeksforgeeks - polymorphism in c++



عقوبة الأداء للعمل مع واجهات في C++؟ (11)

هل هناك عقوبة أداء وقت التشغيل عند استخدام واجهات (فئات قاعدة مجردة) في C ++؟

https://code.i-harness.com


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


استخدام فئات قاعدة مجردة في C ++ عموما استخدام جدول الوظائف الظاهري، كل ما تبذلونه من المكالمات واجهة سيتم النظر من خلال هذا الجدول. تكلفة صغيرة بالمقارنة مع مكالمة وظيفة الخام، لذلك تأكد من أنك تحتاج إلى أن تسير أسرع من ذلك قبل القلق حول هذا الموضوع.


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


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

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


معظم الناس لاحظ عقوبة وقت التشغيل، وبحق.

ومع ذلك، في تجربتي العمل على المشاريع الكبيرة، والفوائد من واجهات واضحة والتغليف السليم تعوض بسرعة المكاسب في السرعة. يمكن تبديل رمز وحدات لتحسين التنفيذ، وبالتالي فإن النتيجة الصافية هي مكسب كبير.

قد تختلف المسافة المقطوعة، وتعتمد بوضوح على التطبيق الذي تقوم بتطويره.


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


هناك عقوبة صغيرة لكل مكالمة وظيفة افتراضية مقارنة مع مكالمة العادية. من غير المحتمل أن تلاحظ فرقا ما لم تكن تقوم بمئات الآلاف من المكالمات في الثانية، والسعر هو في كثير من الأحيان يستحق دفع للوضوح رمز وأضاف على أي حال.


والفرق الرئيسي الوحيد الذي أعرفه هو أنه نظرا لأنك لا تستخدم طبقة ملموسة، فإن الانصهار (أكثر من ذلك بكثير) يصعب القيام به.


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

وهكذا، مع تعدد الميراث (وهو ما واجهات التنفيذ في C ++ هو)، يمكنك دفع الطبقات الأساسية مرات حجم المؤشر في حجم مثيل الكائن. وقد يكون للزيادة في بصمة الذاكرة آثار غير مباشرة على الأداء.


جواب قصير: لا.

الجواب الطويل: ليس الطبقة الأساسية أو عدد الأجداد فئة في تسلسلها الهرمي الذي يؤثر على السرعة. الشيء الوحيد هو تكلفة مكالمة الأسلوب.

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

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


لا يتم تضمين الدالات التي يتم استخدامها باستخدام الإرسال الظاهري

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

تكلفة المكالمة الافتراضية تعتمد على النظام الأساسي

أما بالنسبة للعقوبة النداء المكالمة بالمقارنة مع مكالمة وظيفة عادية، فإن الجواب يعتمد على النظام الأساسي المستهدف. إذا كان لديك تستهدف جهاز كمبيوتر مع وحدة المعالجة المركزية x86 / x64، عقوبة لاستدعاء وظيفة افتراضية صغيرة جدا، وحدة المعالجة المركزية الحديثة x86 / x64 يمكن أن تؤدي التنبؤ فرع على المكالمات غير المباشرة. ومع ذلك، إذا كنت تستهدف بويرك أو بعض منصة ريس الأخرى، قد تكون عقوبة الدعوة الظاهرية كبيرة جدا، لأن المكالمات غير المباشرة لا يمكن التنبؤ بها على بعض المنصات ( بيسي / زبوكس 360 عبر منصة تطوير أفضل الممارسات ).





virtual-functions