سؤال

إذا كان لديك ما يلي:

$var = 3; // we'll say it's set to 3 for this example
if ($var == 4) {
    // do something
} else if ($var == 5) {
    // do something
} else if ($var == 2) {
    // do something
} else if ($var == 3) {
    // do something
} else {
    // do something
}

إذا قل 80٪ من الوقت $var هي 3، هل تقلق بشأن حقيقة أنها تمر بأربع حالات قبل العثور على الحالة الحقيقية؟

أفكر في موقع صغير أنه ليس مشكلة كبيرة، ولكن ماذا عن متى سيتم تشغيل بيان إذا كان هذا 1000 مرة في الثانية؟

أنا أعمل في PHP، ولكن أعتقد أن اللغة لا يهم.

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

المحلول

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

[I سوف التحول إلى تركيب بيثون، فإنه من السهل بالنسبة لي، وأنا متأكد من أنك يمكن تفسير ذلك.]

if var <= 3:
    if var == 2:
        # do something
    elif var == 3:
        # do something
    else: 
        raise Exception
else:
    if var == 4:
        # do something
    elif var == 5:
        # do something
    else:
        raise Exception

وإذا لديك-التصريحات تشكل شجرة بدلا من قائمة مسطحة. كما يمكنك إضافة شروط إلى هذه القائمة، يمكنك تهزهز حول مركز الشجرة. تسلسل شقة من ن مقارنات يأخذ في المتوسط، <م> ن / 2 الخطوات. الشجرة يؤدي إلى سلسلة من المقارنات التي تأخذ السجل (<م> ن ) المقارنات.

نصائح أخرى

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

بعد قولي هذا، كما هو الحال مع كل التحسين:

  1. العمل على انجاحه
  2. قيسها، قم بقياسها
  3. إذا كان سريعًا بما فيه الكفاية، اتركه وشأنه
  4. إذا كان بطيئًا جدًا، فقم بتحسينه

أوه، وربما سأستخدم مفتاحًا/حالة منذ البداية!؛-)

وكانت هناك حالة كلاسيكية من حدوث ذلك (مع حرفيا 5 خيارات كما هو الحال في البريد الخاص بك) في فمبيج، في وظيفة decode_cabac_residual. وهذا مهم إلى حد ما، كما التنميط (مهم جدا - لا تنزعج الأمثل قبل التنميط) أظهر أنه عد لتصل إلى أكثر من 10-15٪ من الوقت الذي يقضيه في H.264 فك الفيديو. بيان إذا تسيطر على مجموعة من البيانات التي تم حسابها بشكل مختلف لأنواع مختلفة من المخلفات ليتم فك الشفرة - و، للأسف، فقدت الكثير من السرعة نظرا لحجم كود إذا تم تكرار وظيفة 5 مرات لكل من 5 أنواع من المتبقية. بدلا من ذلك، كان لا بد من استخدامها وإذا السلسلة.

وقد تم

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

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

إن استخدام بيان التبديل/الحالة هو بالتأكيد الطريق الصحيح هنا.

يمنح هذا المترجم (المترجم) الفرصة لاستخدام جدول الانتقال للوصول إلى الفرع الصحيح دون الحاجة إلى إجراء مقارنات N.فكر في إنشاء مجموعة من العناوين المفهرسة كـ 0، 1، 2، ..بعد ذلك يمكنه فقط البحث عن العنصر الصحيح في المصفوفة في عملية واحدة.

بالإضافة إلى ذلك، نظرًا لأن الحمل النحوي أقل في بيان الحالة، فإنه يُقرأ بسهولة أيضًا.

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

بدلاً من الإجابة على سؤال PHP، سأجيب بشكل عام.لا ينطبق مباشرة على PHP لأنه سيخضع لنوع من التفسير.

يمكن للعديد من المترجمين التحويل من وإلى if-elif-elif-...كتل لتبديل الكتل إذا لزم الأمر والاختبارات في أجزاء elif بسيطة بما فيه الكفاية (ويصادف أن بقية الدلالات متوافقة).بالنسبة للاختبارات من 3 إلى 4، ليس هناك بالضرورة ما يمكن كسبه باستخدام جدول القفز.

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

ومع ذلك، في مثالك، سيدرك معظم المترجمين أن $var هو ثابت 3 ثم يستبدل $var بـ 3 في if..elif..كتل.وهذا بدوره يجعل التعبيرات ثابتة بحيث يتم طيها إما إلى صحيح أو إلى خطأ.يتم قتل جميع الفروع الزائفة بواسطة مزيل الكود الميت ويتم التخلص من اختبار الصواب أيضًا.ما تبقى هو الحالة حيث $var == 3.لا يمكنك الاعتماد على PHP كونها ذكية بالرغم من ذلك.بشكل عام، لا يمكنك نشر $var ولكن قد يكون ذلك ممكنًا من بعض مواقع الاتصال.

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

بيرل 6:

our @code_blocks = (
  { 'Code Block 0' },
  { 'Code Block 1' },
  { 'Code Block 2' },
  { 'Code Block 3' },
  { 'Code Block 4' },
  { 'Code Block 5' },
);

if( 0 <= $var < @code_blocks.length ){
  @code_blocks[$var]->();
}

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

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

مع التعليمات البرمجية حيث هو محض تحليل المساواة وأود أن نقله إلى التحول / حالة، والتي توفر أداء أفضل.

$var = 3; // we'll say it's set to 3 for this example
switch($var)
 {
   case 4:
      //do something
      break;
   case 5:
      //do something
      break;
   case:
      //do something when none of the provided cases match (same as using an else{ after the elseif{
 }

والآن إذا كان لديك عمل مقارنات أكثر تعقيدا وأود إما عش لهم في التبديل، أو مجرد استخدام ELSEIF.

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

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

ووقت ذلك. ترى كم مرة ثانية أن تتمكن من تشغيل أعلاه إذا / آخر إذا / بيان آخر مع أي إجراء المتخذة و$ فار لا يجري واحدة من الخيارات.

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