سؤال

string strLine;//not constant
int index = 0;
while(index < strLine.length()){//strLine is not modified};

كم مرة strLine.length() يتم تقييم

هل نحن بحاجة إلى وضع استخدام nLength مع nLength المخصصة لstrLine.length() قبل حلقة

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

المحلول

وlength سيتم تقييم كل مرة تذهب من خلال الحلقة، ولكن منذ length حان الوقت ثابت (O(1)) لا يغير من الأمر كثيرا، وسوف إضافة متغير لتخزين هذه القيمة ربما يكون لها تأثير يذكر مع ضربة صغيرة على كود قراءة (وكذلك كسر رمز إذا تم تغيير سلسلة من أي وقت مضى).

نصائح أخرى

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

وفي كل مرة يطلق عليه ... (كل تقييم الوقت). إذا كنت لا تغيير سلسلة طول كنت أفضل مع متغير مؤقت مثل:

string strLine;
int stringLength = strLine.length();
int index = 0;
while(index < stringLength);

وأعتقد أن هناك سؤال ثان الكامنة داخل هذا، وهذا هو "الذي التنفيذ هو أكثر وضوحا؟"

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

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

وقال: "ترك الأمر كما استدعاء دالة؛ والمترجم تحسين أنه" يبدو لي pessimization سابق لأوانه. على الرغم من طول () هو O (1)، إن لم يكن inlined (لا يمكنك ضمان أن أمثل ليست المعوقين) انها لا تزال استدعاء دالة غير بديهي. باستخدام متغير محلي، لتوضيح المعنى الخاص، وتحصل على الأداء الأمثل ربما غير تافهة.

هل ما يجعل نيتك أكثر وضوحا.

وstrLine.length () سيتم تقييم بينما (ط

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

إذا كنت تنوي استخدام استخدام متغير زمانيا تصفيات CONST، وبالتالي فإن المترجم يمكن أن تضيف تحسينات مع العلم أن القيمة لن تتغير:

string strLine;//not constant
int index = 0;
const int strLenght = strLine.Length();
while(index < strLine.length()){//strLine is not modified};

وهناك احتمالات بأن المترجم نفسه جعل تلك التحسينات عند الوصول إلى أسلوب طول () على أي حال.

وتحرير: التجمع هو بلدي قليلا صدئ، ولكن أعتقد أن التقييم يحدث مرة واحدة فقط. ونظرا لهذا كود:

int main()
{
    std::string strLine="hello world";

    for (int i=0; i < strLine.length(); ++i)
    {
        std::cout << strLine[i] <<std::endl;
    }
}

ويولد هذا التجمع:

    for (int i=0; i < strLine.length(); ++i)
0040104A  cmp         dword ptr [esp+20h],esi 
0040104E  jbe         main+86h (401086h)

ولكن لهذا الرمز

 std::string strLine="hello world";
 const int strLength = strLine.length();
 for (int i=0; i < strLength ; ++i)
 {
    std::cout << strLine[i] <<std::endl;
 }

ويولد هذا واحد:

   for (int i=0; i < strLength ; ++i)
0040104F  cmp         edi,esi 
00401051  jle         main+87h (401087h) 

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

وحاول مع VSC ++ 2005

وكما ذكر، منذ المرجح أن يتم تعريف الدالة string::length تماما في الرأس، ويشترط أن يكون O (1)، فإنه من شبه المؤكد أن تقييم إلى الوصول عضو بسيط، والحصول على inlined في التعليمات البرمجية. منذ كنت لا تعلن سلسلة كما متقلبة، ولا يسمح للمترجم أن نتصور أن أي رمز الخارجي هو الذهاب الى تغييره، والدعوة إلى تحسين الوصول إلى الذاكرة واحد وترك القيمة في السجل إذا وجدت أن هذا هو فكرة جيدة.

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

وبما انك لم يتم تغيير سلسلة، لا ينبغي أن تستخدم

const string strLine;

وفقط، لأن ثم المترجم يحصل على بعض مزيد من المعلومات حول ما يمكن وما لا يمكن تغيير - لست متأكدا بالضبط كيف الذكية وC ++ مترجم يمكن ان تحصل، على الرغم

وسيتم تقييم strLine.length() في كل مرة تذهب حول الحلقة.

وأنت في الصحيح أنه سيكون أكثر فعالية لاستخدام nLength، وخاصة إذا strLine طويلة.

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