سؤال

أو هو كل شيء عن دلالات الألفاظ ؟

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

المحلول

الجواب القصير:لا أنها هي بالضبط نفس.

أعتقد أنه يمكن من الناحية النظرية تعتمد على مترجم;حقا كسر واحدة قد تفعل شيئا مختلفا قليلا لكني سأشعر بالدهشة.

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

int main()
{
#if 1
    int i = 10;
    do { printf("%d\n", i); } while(--i);
#else
    int i = 10;
    for (; i; --i) printf("%d\n", i);
#endif
}

تحرير: هنا هو "البرتقال مع البرتقال" في حين حلقة سبيل المثال أيضا يجمع أسفل إلى نفس الشيء:

    while(i) { printf("%d\n", i); --i; }

نصائح أخرى

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

وعلى سبيل المثال في بعض التجارب فعلت قبل بضع سنوات،

for (int i = 0; i < 10; i++)
{
...
}

و

int i = 0;
do
{
  ...
  i++;
}
while (i < 10);

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

لا يوجد الدلالي الفرق ، هناك حاجة إلى أي جمعت الفرق.ولكن ذلك يعتمد على مترجم.لذلك حاولت مع g++ 4.3.2, CC 5.5 ، xlc6.

g++, CC كانت متطابقة ، xlc لا

الفرق في xlc كان في الأولي حلقة دخول.

extern int doit( int );
void loop1( ) {
  for ( int ii = 0; ii < 10; ii++ ) {
    doit( ii );
  }
}

void loop2() {
  int ii = 0; 
  while ( ii < 10 ) {
    doit( ii );
    ii++;
  }
}

XLC الانتاج

.loop2:                                 # 0x00000000 (H.10.NO_SYMBOL)
    mfspr   r0,LR
    stu     SP,-80(SP)
    st      r0,88(SP)
    cal     r3,0(r0)
    st      r3,64(SP)
    l       r3,64(SP)  ### DIFFERENCE ###
    cmpi    0,r3,10
    bc      BO_IF_NOT,CR0_LT,__L40
...
enter code here
.loop1:                                 # 0x0000006c (H.10.NO_SYMBOL+0x6c)
    mfspr   r0,LR
    stu     SP,-80(SP)
    st      r0,88(SP)
    cal     r3,0(r0)
    cmpi    0,r3,10    ### DIFFERENCE ###
    st      r3,64(SP)
    bc      BO_IF_NOT,CR0_LT,__La8
...

ونطاق المتغير في اختبار للحلقة while هو أوسع من نطاق المتغيرات في رأس حلقة for.

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

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

والمترجمات التي تحسن استخدام حلقة الفتح وربما تفعل ذلك إلا في حالة لحلقة.

وكلاهما ما يعادلها. انها مسألة من دلالات.

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

i = 1; do { ... i--; } while( i > 0 ); 

وبدلا من

for(  i = 1; i > 0; --i )
{ ....
}  

وأنا أكتب المجمعين. نحن تجميع كل "منظم" التحكم في التدفق (if، while، for، switch، do ... while) في فروع المشروطة وغير المشروطة. ثم نقوم بتحليل الرسم البياني ضبط التدفق. منذ مترجم C للتعامل مع goto عام على أي حال، فمن الأسهل للحد من كل شيء لتعليمات فرع وفرع المشروط، ثم التأكد من التعامل مع هذه الحالة أيضا. (A مترجم C له علاقة بعمل جيد ليس فقط على كود مكتوبة بخط اليد ولكن القانون أيضا على تتولد تلقائيا، التي قد يكون لها العديد والعديد من البيانات goto).

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

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

والدليل على أنه قد يكون هناك فرق: هذه خطوط إنتاج مختلفة رمز التجميع باستخدام cc65

for (; i < 1000; ++i);   
while (i < 1000) ++i;

في اتميل ATMEGA بينما () أسرع من ل(). لماذا يفسر هذا في AVR035: كفاءة C ترقيمها لAVR

وP.S. لم تذكر منصة الأصلية في المسألة.

تواصل يتصرف بشكل مختلف في بالنسبة و في حين:في بالنسبة, ، فإنه يغير العداد ، في حين, عادة لا

إضافة إلى جواب آخر:في تجربتي ، وتحسين البرامج مثل كبيرة ، كث اللحية يجري حلق الرجل.

  • أولا وتقطعه في قطع كبيرة مع مقص (تقليم كل أطرافه من شجرة).
  • ثم جعلها قصيرة مع كهربائي المقص (قرص خوارزميات).
  • وأخيرا هل يحلق مع الحلاقة للتخلص من الماضي قليلا (منخفضة المستوى الأمثل).

الماضي حيث الفرق بين for() و while() ربما, ولكن ربما لن تحدث فرقا.

P. S.المبرمجين أعلم (الذين هم كل شيء جيد جدا, وأظن عينة) أساسا تذهب في الاتجاه الآخر.

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

وهناك فرق في بعض الحالات.

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

هو while() أسرع/أبطأ من for()?دعونا استعراض عدد قليل من الأشياء حول التحسين:

  • مترجم الكتاب العمل من الصعب جدا أن يحلق دورات من خلال وجود عدد أقل من يدعو إلى القفز, مقارنة, الزيادة, و أنواع أخرى من التعليمات التي تولد.

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

  • كما المبرمجين نكتب الكثير من المكالمات وظيفة بعض لأننا أقصد أن بعض لأننا كسول بعض لأن المترجم زلات لهم دون أن تكون واضحة.

  • معظم الوقت, لا يهم, لأن الأجهزة سريعة جدا, و لدينا وظائف صغيرة جدا لدرجة أن الكمبيوتر هو مثل كلب صيد الكلب الذي wolfes لها الطعام و يطرح أكثر.

  • في بعض الأحيان, ومع ذلك ، فإن وظيفة كبيرة بما يكفي أن الأداء هو قضية.

  • ماذا نفعل بعد ذلك ؟ حيث هو أكبر ربح ؟

    • الحصول على المترجم أن يحلق بضع دورات خارج الحلقات & مثل هذا ؟
    • العثور على وظيفة المكالمات التي لا -حقا- تحتاج إلى القيام به كثيرا ؟
  • المترجم لا يمكن أن تفعل هذا الأخير.فقط نحن المبرمجين.

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

  • المحللون هي البداية. أنا أفعل هذا.

ملفق اقتباس من ويلي ساتون عندما سئل لماذا تسرق البنوك ؟ :
لأن هذا هو حيث يوجد المال.

إذا كنت ترغب في توفير دورات ، ومعرفة أين هم.

ربما فقط أسلوب الترميز.

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