जबकि (1) बनाम। (;) के लिए गति में अंतर है?


154

दीर्घ संस्करण...

एक सहकर्मी ने आज while (1)एक पर्ल लिपि में मेरे प्रयोग को देखने के बाद जोर दिया for (;;)। मैंने तर्क दिया कि उन्हें उम्मीद है कि दुभाषिया किसी भी मतभेद का अनुकूलन करेगा। मैंने एक स्क्रिप्ट स्थापित की जो लूप पुनरावृत्तियों के लिए 1,000,000,000 चलाएगी और लूप की समान संख्या और बीच के समय को रिकॉर्ड करेगी। मुझे कोई सराहनीय अंतर नहीं मिला। मेरे सह-कार्यकर्ता ने कहा कि एक प्रोफेसर ने उनसे कहा था कि while (1)तुलना कर रहे थे 1 == 1और for (;;)नहीं कर रहे थे। हमने सी + + के साथ पुनरावृत्तियों की संख्या 100x के साथ एक ही परीक्षण दोहराया और अंतर नगण्य था। हालांकि यह एक ग्राफिक उदाहरण था कि एक स्क्रिप्टिंग भाषा बनाम कितना तेज संकलित कोड हो सकता है।

लघु संस्करण...

वहाँ एक पसंद करते हैं किसी भी कारण है while (1)एक से अधिक for (;;)है, तो आप एक अनंत लूप से बाहर तोड़ने के लिए की जरूरत है?

नोट: यदि यह प्रश्न से स्पष्ट नहीं है। यह विशुद्ध रूप से दोस्तों के एक जोड़े के बीच एक मजेदार अकादमिक चर्चा थी। मुझे पता है कि यह एक सुपर महत्वपूर्ण अवधारणा नहीं है जिसे सभी प्रोग्रामर को समझाना चाहिए। सभी महान उत्तरों के लिए धन्यवाद (और मुझे यकीन है कि अन्य) इस चर्चा से कुछ चीजें सीख चुके हैं।

अद्यतन: उपर्युक्त सह-कार्यकर्ता नीचे एक प्रतिक्रिया के साथ तौला।

यदि उसे दफनाया जाता है तो यहां उद्धृत किया जाता है।

यह एक एएमडी विधानसभा प्रोग्रामर से आया था। उन्होंने कहा कि सी प्रोग्रामर (कवि) को एहसास नहीं है कि उनके कोड में अक्षमताएं हैं। उन्होंने कहा कि आज, जीसीसी संकलक बहुत अच्छे हैं, और उनके जैसे लोगों को व्यवसाय से बाहर कर देते हैं। उन्होंने उदाहरण के लिए कहा, और मुझे while 1बनाम के बारे में बताया for(;;)। मैं इसका उपयोग अब आदत से बाहर कर रहा हूं, लेकिन जीसीसी और विशेष रूप से दुभाषिए इन दोनों दिनों के लिए एक ही ऑपरेशन (एक प्रोसेसर जंप) करेंगे, क्योंकि वे अनुकूलित हैं।


4
मैं उत्सुक हूँ। पर्ल लिपि में अनंत लूप की आवश्यकता क्यों है? आप स्पष्ट रूप से एक ड्राइवर या एक सिस्टम चीज़ की प्रोग्रामिंग नहीं कर रहे हैं ... अनंत बहुत लंबा है :-)
ल्यूक एम

125
कौन सा अनंत लूप सबसे तेज है? LOL ... "मेरा नया कंप्यूटर इतना तेज है, यह सिर्फ एक घंटे के भीतर एक अनंत लूप चलाता है ..." ;-)
अर्जन आइंबू

8
क्या वह समाजशास्त्र के प्रोफेसर थे जिन्होंने उन्हें बताया था? आधुनिक युग में, आपके द्वारा टाइप किया गया कोड वह नहीं है जिसे कंप्यूटर देखते हुए समाप्त करता है।
ब्रायन डी फॉय

5
मुझे उम्मीद है कि यह परीक्षण करने के लिए जितना समय आपको लगता है, वह संभवतः उस समय की मात्रा से कहीं अधिक है जो संभावित रूप से यह जानकर बचा लिया जाता है कि कौन सा तेज है, यदि है। भले ही आप प्रोग्रामिंग के अपने दोनों जीवनकाल में इसे परिशोधन करें।
पीटर रेफर

4
कंपाइलर कभी भी ऐसा टेस्ट करने के लिए कोड जनरेट करेगा कि उसे पता है कि इसका कोई साइड इफेक्ट नहीं है और नतीजा यह है कि कंपाइलर को पहले से पता है? इसका कोई अर्थ नही बन रहा है।
डेविड श्वार्ट्ज

जवाबों:


218

पर्ल में, वे एक ही opcodes में परिणाम:

$ perl -MO=Concise -e 'for(;;) { print "foo\n" }'
a  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 2 -e:1) v ->3
9     <2> leaveloop vK/2 ->a
3        <{> enterloop(next->8 last->9 redo->4) v ->4
-        <@> lineseq vK ->9
4           <;> nextstate(main 1 -e:1) v ->5
7           <@> print vK ->8
5              <0> pushmark s ->6
6              <$> const[PV "foo\n"] s ->7
8           <0> unstack v ->4
-e syntax OK

$ perl -MO=Concise -e 'while(1) { print "foo\n" }'
a  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 2 -e:1) v ->3
9     <2> leaveloop vK/2 ->a
3        <{> enterloop(next->8 last->9 redo->4) v ->4
-        <@> lineseq vK ->9
4           <;> nextstate(main 1 -e:1) v ->5
7           <@> print vK ->8
5              <0> pushmark s ->6
6              <$> const[PV "foo\n"] s ->7
8           <0> unstack v ->4
-e syntax OK

इसी तरह जीसीसी में:

#include <stdio.h>

void t_while() {
    while(1)
        printf("foo\n");
}

void t_for() {
    for(;;)
        printf("foo\n");
}

    .file   "test.c"
    .section    .rodata
.LC0:
    .string "foo"
    .text
.globl t_while
    .type   t_while, @function
t_while:
.LFB2:
    pushq   %rbp
.LCFI0:
    movq    %rsp, %rbp
.LCFI1:
.L2:
    movl    $.LC0, %edi
    call    puts
    jmp .L2
.LFE2:
    .size   t_while, .-t_while
.globl t_for
    .type   t_for, @function
t_for:
.LFB3:
    pushq   %rbp
.LCFI2:
    movq    %rsp, %rbp
.LCFI3:
.L5:
    movl    $.LC0, %edi
    call    puts
    jmp .L5
.LFE3:
    .size   t_for, .-t_for
    .section    .eh_frame,"a",@progbits
.Lframe1:
    .long   .LECIE1-.LSCIE1
.LSCIE1:
    .long   0x0
    .byte   0x1
    .string "zR"
    .uleb128 0x1
    .sleb128 -8
    .byte   0x10
    .uleb128 0x1
    .byte   0x3
    .byte   0xc
    .uleb128 0x7
    .uleb128 0x8
    .byte   0x90
    .uleb128 0x1
    .align 8
.LECIE1:
.LSFDE1:
    .long   .LEFDE1-.LASFDE1
.LASFDE1:
    .long   .LASFDE1-.Lframe1
    .long   .LFB2
    .long   .LFE2-.LFB2
    .uleb128 0x0
    .byte   0x4
    .long   .LCFI0-.LFB2
    .byte   0xe
    .uleb128 0x10
    .byte   0x86
    .uleb128 0x2
    .byte   0x4
    .long   .LCFI1-.LCFI0
    .byte   0xd
    .uleb128 0x6
    .align 8
.LEFDE1:
.LSFDE3:
    .long   .LEFDE3-.LASFDE3
.LASFDE3:
    .long   .LASFDE3-.Lframe1
    .long   .LFB3
    .long   .LFE3-.LFB3
    .uleb128 0x0
    .byte   0x4
    .long   .LCFI2-.LFB3
    .byte   0xe
    .uleb128 0x10
    .byte   0x86
    .uleb128 0x2
    .byte   0x4
    .long   .LCFI3-.LCFI2
    .byte   0xd
    .uleb128 0x6
    .align 8
.LEFDE3:
    .ident  "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
    .section    .note.GNU-stack,"",@progbits

इसलिए मुझे लगता है कि उत्तर है, वे कई संकलक में समान हैं। बेशक, कुछ अन्य संकलक के लिए यह जरूरी नहीं हो सकता है, लेकिन संभावना है कि लूप के अंदर कोड वैसे भी लूप की तुलना में कुछ हजार गुना अधिक महंगा होने वाला है, इसलिए कौन परवाह करता है?


15
बी के साथ की कोशिश करें :: डिपार्स, लूप के लिए एक अनन्तता का चित्रण करते हुए थोड़ी देर का लूप देता है: पी
केंट फ्रेड्रिक

27
"पर्ल में, वे एक ही opcodes में परिणाम" ... हाँ, लेकिन जो तेजी से है? :-)
टिन मैन

6
मुझे लगता है कि प्रिंट () के लिए gcc के स्थानापन्न पुट () है, क्योंकि केवल एक ही तर्क है और इसलिए प्रारूपित करने के लिए कुछ भी नहीं है - तेज और अधिक सुरक्षित! (gcc भी चर तर्क सूची के विरुद्ध फ़ॉर्मेटिंग टैग की जाँच करता है।)
ली डी

@ टिन मैन: वे समतुल्य हैं, क्योंकि कंप्यूटर एक ही सटीक ऑपरेशन करता है: P
BlackBear

1
@snap, यह 'पूरी तरह से' गलत नहीं है, यह सिर्फ रनटाइम लागत पर ध्यान केंद्रित कर रहा है। मैं कल्पना नहीं कर सकता कि किस तरह की स्थिति के परिणामस्वरूप अनंत लूपों के पार्सिंग समय में महत्वपूर्ण निर्णय लेने का कारक होगा कि आपका कार्यक्रम कितनी तेजी से चलता है
bdonlan

55

जीसीसी का उपयोग करते हुए, वे दोनों एक ही विधानसभा भाषा के लिए संकलित लगते हैं:

L2:
        jmp     L2

20
-S विकल्प के साथ GCC का उपयोग करना (इकट्ठा करना, लिंक न करना)
मार्टिन कोटे

54

एक के बाद एक को पसंद करने के लिए ज्यादा कारण नहीं है। मुझे लगता है कि while(1)और विशेष रूप while(true)से अधिक पठनीय हैं for(;;), लेकिन यह सिर्फ मेरी प्राथमिकता है।


94
# डेफ़िन ईवर ;; के लिए (कभी) मैं हमेशा मनोरंजक की तरह है कि मिल गया है।
टॉम

19
कैसे के बारे में #define कभी (;;) हमेशा के लिए;
मार्टिन कोटे

16
दोनों सतह पर अधिक पठनीय लगते हैं, लेकिन मैं अपने रखरखाव प्रोग्रामर (आमतौर पर मुझे) के लिए नए खोजशब्दों को परिभाषित नहीं करने की कोशिश करता हूं ताकि उसके सिर को खरोंच कर दिया जा सके।
छिपकली का बिल

13
@Martin जो काम नहीं करेगा, क्योंकि # परिभाषित एक टोकन के भीतर प्रतिस्थापित नहीं होता है, और foreverयह स्वयं टोकन है।
लिली चुंग

2
"मैं अपने रखरखाव के लिए नए कीवर्ड्स को परिभाषित नहीं करने की कोशिश करता हूं" - अगर केवल अधिक लोगों ने ही यह रवैया अपनाया तो मैं इन सभी अयोग्य और जादुई स्लीप-ऑफ-हैंड शेंनिगन्स पर हर बार जब मैं घूमता हूं, तो मैं उनसे नहीं टकराऊंगा!
tchrist

31

मानक के अनुसार कोई अंतर नहीं है। 6.5.3 / 1 है:

बयान के लिए

for ( for-init-statement ; conditionopt ; expressionopt ) statement

के बराबर है

{
  for-init-statement
  while ( condition ) {
    statement
    expression ;
  }
}

और 6.5.3 / 2 है:

या तो स्थिति और अभिव्यक्ति दोनों को छोड़ा जा सकता है। एक लापता स्थिति, जबकि (सच) के बराबर क्लॉज के लिए निहित है।

तो C ++ मानक के अनुसार कोड:

for (;;);

बिल्कुल वैसा ही है:

{
  while (true) {
    ;
    ;
  }
}

4
यह उत्पन्न कोड या प्रदर्शन से संबंधित नहीं है। मानक केवल कार्यक्षमता को परिभाषित करता है। बेशक, प्रदर्शन समान होगा।
पोटाटोस्वाटर

1
मुझे विश्वास नहीं है कि यह सच है कि प्रदर्शन में अंतर, जैसा कि नियम का उल्लंघन करता है। यदि ऐसा होता, तो कंपाइलरों को अपने कोड को यथा-नियम के तहत गति देने की अनुमति नहीं होती, उदाहरण के लिए स्वतंत्र विवरणों को फिर से आदेश देकर। संकलक वास्तव में ऐसा ही करते हैं। लेकिन मेरे मानक की नकल ऊपर की तरफ है।
स्टीव जेसप 14

28

विजुअल C ++ कंपाइलर एक चेतावनी के लिए उपयोग किया जाता है

while (1) 

(निरंतर अभिव्यक्ति) लेकिन के लिए नहीं

for (;;)

मैंने for (;;)उस कारण को प्राथमिकता देने का अभ्यास जारी रखा है , लेकिन मुझे नहीं पता कि कंपाइलर अभी भी ऐसा करता है या नहीं।


चेतावनी शायद तब है जब आपने इस्तेमाल किया था (1) जबकि (सच्चा)
jrharshath

16
सत्य एक स्थिरांक है। जबकि (सत्य) एक स्थिर अभिव्यक्ति है। रुचि रखने वाले किसी व्यक्ति के लिए, चेतावनी C4127 यहां दी गई है: msdn.microsoft.com/en-us/library/6t66728h(VS.80).aspx
sean e

हां, चेतावनी अभी भी 1 और सच दोनों के लिए मौजूद है। यही कारण है कि मैं हमेशा (;;) के लिए उपयोग करता हूं
एल्विस स्ट्रैजडिन्स

26

for(;;) टाइप करने के लिए एक कम वर्ण है यदि आप चीजों को अनुकूलित करने के लिए उस दिशा में जाना चाहते हैं।


21
गोल्फ के लिए जानना अच्छा है। अन्यथा एक सिंटैक्स चुनने का एक खराब कारण।
एडम बेलेयर

@AdamBellaire Terseness अक्सर एक निश्चित कौशल सीमा से ऊपर, पठनीयता बढ़ाती है।
वेक्टर गोरगोथ 20

20

इस पुराने संकलक के साथ टर्बो सी का for(;;)परिणाम तेजी से कोड में आता है while(1)

आज जीसीसी, विजुअल सी (मुझे लगता है कि लगभग सभी) कंपाइलर अच्छी तरह से अनुकूलन करते हैं, और 4.7 मेगाहर्ट्ज वाले सीपीयू शायद ही कभी उपयोग किए जाते हैं।

उन दिनों में एक for( i=10; i; i-- )की तुलना में तेजी थी for( i=1; i <=10; i++ ), क्योंकि तुलना i0 है, सीपीयू-जीरो-फ्लैग सशर्त कूद में परिणाम। और जीरो-फ़्लैग को अंतिम डिक्रिमेंट ऑपरेशन के साथ संशोधित किया गया था ( i-- ), अतिरिक्त सीएमपी-ऑपरेशन की आवश्यकता नहीं है।

    call    __printf_chk
    decl    %ebx          %ebx=iterator i 
    jnz     .L2
    movl    -4(%ebp), %ebx
    leave

और यहाँ for(i=1; i<=10; i++)अतिरिक्त cmpl के साथ:

    call    __printf_chk
    incl    %ebx
    cmpl    $11, %ebx
    jne     .L2
    movl    -4(%ebp), %ebx
    leave

13

बहस करने वाले सभी लोगों के लिए, आपको लूप करते समय अनिश्चित काल का उपयोग नहीं करना चाहिए, और खुले गोटो के उपयोग की तरह दफ्तरी सामान का सुझाव देना (गंभीरता से, ouch)

while (1) {
     last if( condition1 );
     code();
     more_code(); 
     last if( condition2 ); 
     even_more_code(); 
}

वास्तव में किसी अन्य तरीके से प्रभावी ढंग से प्रतिनिधित्व नहीं किया जा सकता है। एग्जिट वैरिएबल बनाए बिना और इसे सिंक करने के लिए काला जादू न करें।

यदि आपके पास अधिक गोटो-एस्क सिंटैक्स के लिए एक पेनकांत है, तो गुंजाइश को सीमित करने वाले कुछ समझदार का उपयोग करें।

flow: { 

   if ( condition ){ 
      redo flow;
   }
   if ( othercondition ){ 
       redo flow;
   }
   if ( earlyexit ){ 
       last flow;
   }
   something(); # doesn't execute when earlyexit is true 
}

अंततः स्पीड इतना महत्वपूर्ण नहीं है

इस बारे में चिंता करना कि प्रभावी गति बुद्धिमान विभिन्न लूपिंग निर्माण समय की भारी बर्बादी है। समय से पहले और बाद में अनुकूलन। मैं किसी भी स्थिति के बारे में सोच नहीं सकता, जहां मैंने कभी देखा हो कि प्रोफाइलिंग कोड ने लूपिंग कंस्ट्रक्शन के मेरी पसंद में अड़चनें पाईं।

आम तौर पर इसका लूप कैसे और लूप का क्या होता है।

आपको पठनीयता और पर्याप्तता के लिए "अनुकूलन" करना चाहिए, और जो कुछ भी आपके कोड को ढूंढता है उसे अगले गरीब चूसने वाले को समझाने में सबसे अच्छा है।

यदि आप किसी को बताए गए "गेटो लेबल" ट्रिक का उपयोग करते हैं, और मुझे आपके कोड का उपयोग करना है, तो एक आंख के साथ सोने के लिए तैयार रहें, खासकर यदि आप इसे एक से अधिक बार करते हैं, क्योंकि उस तरह का सामान भयानक रूप से स्पेगेटी कोड बनाता है ।

सिर्फ इसलिए कि आप स्पेगेटी कोड बना सकते हैं इसका मतलब यह नहीं है कि आपको चाहिए


9

स्ट्रॉस्ट्रुप से, टीसी ++ पीएल (तीसरा संस्करण), .16.1.1:

जिज्ञासु for (;;)लूप एक अनंत लूप को निर्दिष्ट करने का मानक तरीका है; आप इसे "हमेशा के लिए" उच्चारण कर सकते हैं। [...] while (true)एक विकल्प है।

मैं पसंद करता हूं for (;;)


9

यदि कंपाइलर कोई अनुकूलन नहीं करता है, for(;;)तो हमेशा की तुलना में तेज़ होगा while(true)। ऐसा इसलिए है क्योंकि स्टेटमेंट हर बार स्थिति का मूल्यांकन करता है, लेकिन फॉर-स्टेटमेंट एक बिना शर्त कूद है। लेकिन अगर कंपाइलर नियंत्रण प्रवाह का अनुकूलन करता है, तो यह कुछ ऑपकोड उत्पन्न कर सकता है। आप disassembly के कोड को बहुत आसानी से पढ़ सकते हैं।

पुनश्च आप इस तरह एक अनंत लूप लिख सकते हैं:

#define EVER ;;
  //...
  for (EVER) {
    //...
  }

आधुनिक दिन और उम्र में कभी भी ईवीएस (किशोर भाषण) को प्रतिस्थापित नहीं किया जाना चाहिए! गंभीरता से हालांकि मैं सिर्फ (;;) {} के लिए उपयोग करता हूं। मैंने बहुत पहले ऑनलाइन पढ़ा था कि दोनों के बीच के अंतर के बारे में (जब मैं छोटा था और वास्तव में नहीं जानता था कि वे एक ही हैं) और मैंने जो पढ़ा है उसके साथ बस अटक गया।
बजा

8

मैंने इस बारे में एक बार सुना था।

यह एक एएमडी विधानसभा प्रोग्रामर से आया था। उन्होंने कहा कि सी प्रोग्रामर (लोग) को यह पता नहीं है कि उनके कोड में अक्षमताएं हैं। उन्होंने कहा कि आज, जीसीसी संकलक बहुत अच्छे हैं, और उनके जैसे लोगों को व्यवसाय से बाहर कर देते हैं। उन्होंने उदाहरण के लिए कहा, और मुझे while 1बनाम के बारे में बताया for(;;)। मैं इसे अब आदत से बाहर कर रहा हूं, लेकिन जीसीसी और विशेष रूप से दुभाषिए इन दोनों दिनों के लिए एक ही ऑपरेशन (एक प्रोसेसर जंप) करेंगे, क्योंकि वे अनुकूलित हैं।


5

संकलित भाषा के अनुकूलित निर्माण में, दोनों के बीच कोई प्रशंसनीय अंतर नहीं होना चाहिए। न ही रनटाइम पर किसी भी तुलना का प्रदर्शन करना चाहिए, वे लूप कोड को तब तक निष्पादित करेंगे जब तक कि आप मैन्युअल रूप से लूप से बाहर न निकल जाएं (जैसे कि ए break)।


3

मैं हैरान हूँ कि कोई भी ठीक से परीक्षण किया for (;;)बनाम while (1)पर्ल में!

क्योंकि पर्ल की व्याख्या की गई भाषा है, एक पर्ल स्क्रिप्ट को चलाने का समय केवल निष्पादन चरण (जो इस मामले में एक ही है) से नहीं होता है, बल्कि निष्पादन से पहले व्याख्या चरण भी होता है। गति की तुलना करते समय इन दोनों चरणों को ध्यान में रखा जाना चाहिए।

सौभाग्य से पर्ल के पास एक सुविधाजनक बेंचमार्क मॉड्यूल है जिसे हम बेंचमार्क को लागू करने के लिए उपयोग कर सकते हैं जैसे कि:

#!/usr/bin/perl -w

use Benchmark qw( cmpthese );

sub t_for   { eval 'die; for (;;) { }'; }
sub t_for2  { eval 'die; for (;;)  { }'; }
sub t_while { eval 'die; while (1) { }'; }

cmpthese(-60, { for => \&t_for, for2 => \&t_for2, while => \&t_while });

ध्यान दें कि मैं लूप के लिए अनंत के दो अलग-अलग संस्करणों का परीक्षण कर रहा हूं: एक जो कि लूप से कम है और दूसरा वह जो लूप के समान लंबाई बनाने के लिए एक अतिरिक्त स्थान रखता है।

उबंटू 11.04 x86_64 पर perl 5.10.1 के साथ मुझे निम्नलिखित परिणाम प्राप्त हुए हैं:

          जबकि for2 के लिए दर
100588 / s के लिए - -0% -2%
for2 100937 / s 0% - -1%
जबकि 102147 / s 2% 1% -

जबकि लूप स्पष्ट रूप से इस प्लेटफॉर्म पर विजेता है।

FreeBSD 8.2 x86_64 पर पर्ल 5.14.1 के साथ:

         जबकि for2 के लिए दर
53453 / s के लिए - -0% -2%
for2 53552 / s 0% - -2%
जबकि 54564 / s 2% 2% -

जबकि पाश यहां भी विजेता है।

FreeBSD 8.2 i386 पर perl 5.14.1 के साथ:

         For2 के लिए दर
जबकि 24311 / s - -1% -1%
24481 / s 1% के लिए - -1%
for2 24637 / s 1% 1% -

आश्चर्यजनक रूप से एक अतिरिक्त स्थान के साथ लूप के लिए यहां सबसे तेज़ विकल्प है!

मेरा निष्कर्ष यह है कि यदि प्रोग्रामर गति के लिए अनुकूलन कर रहा है तो x86_64 प्लेटफॉर्म पर लूप का उपयोग किया जाना चाहिए। अंतरिक्ष के लिए अनुकूलन करते समय स्पष्ट रूप से एक लूप का उपयोग किया जाना चाहिए। अन्य प्लेटफार्मों के संबंध में मेरे परिणाम दुर्भाग्य से अनिर्णायक हैं।


9
निष्कर्ष स्पष्ट रूप से गलत है। Benchmarkयदि इसकी सीमाएँ एक दूसरे से 7% के भीतर हों तो इसका उपयोग धीमी गति से अलग करने के लिए नहीं किया जा सकता है। इसके अलावा, आपने forऔर whileछोरों के बीच के अंतर का परीक्षण नहीं किया है क्योंकि प्रत्येक उप dieस्वयं छोरों तक पहुंचने से पहले होगा । और जब से व्हेलस्पेस की राशि पर्ल इंटरप्रेटर के लिए मायने रखती है? क्षमा करें, लेकिन विश्लेषण अत्यंत त्रुटिपूर्ण है।
ज़ैद

2
@Zaid, आपकी टिप्पणियों के लिए धन्यवाद! क्या आप अपना स्वयं का उत्तर पोस्ट करने का मन करेंगे ताकि हर कोई उससे सीख सके? :) dieमेरे कोड में वहाँ है क्योंकि मेरा इरादा केवल संकलन समय अंतर का परीक्षण करना है । जैसा कि अन्य लोग पहले ही बता चुके हैं कि परिणामी बाइट-कोड समान है, इस प्रकार परीक्षण का कोई मतलब नहीं है। आश्चर्यजनक रूप से सफेद स्थान की मात्रा मेरे परीक्षण वातावरण में इस मामले में एक छोटा सा अंतर बनाती है। यह कुछ इस तरह से हो सकता है कि स्मृति में संरेखित होने वाले पात्रों को कैसे समाप्त किया जाए या कुछ इसी तरह ...
Snap

4
मुझे उत्तर पोस्ट करने की आवश्यकता नहीं है क्योंकि मैं जो कहूंगा वह पहले से ही bdonlan द्वारा उल्लिखित है। और यहां तक ​​कि अगर आप संकलन समय की तुलना कर रहे हैं, तो संख्या जो Benchmarkअनिर्णायक है। उस 1% अंतर पर भरोसा मत करो!
ज़ैद

केवल 60 पुनरावृत्तियों? अधिक सटीक सापेक्ष समय प्राप्त करने के लिए 5 मिनट के लिए परीक्षण चलाएं।
डक डक

-6060 सेकंड के लिए परीक्षण चलाता है।
स्नैप करें

2

सिद्धांत रूप में, एक पूरी तरह से अनुभवहीन कंपाइलर बाइनरी (बर्बाद करने वाले स्थान) में शाब्दिक '1' को संग्रहीत कर सकता है और यह देखने के लिए जांच कर सकता है कि क्या 1 == 0 प्रत्येक पुनरावृत्ति (समय और अधिक स्थान बर्बाद कर रहा है)।

वास्तविकता में, हालांकि, "नहीं" अनुकूलन के साथ, कंपाइलर अभी भी दोनों को समान रूप से कम कर देंगे। वे चेतावनी भी दे सकते हैं क्योंकि यह एक तार्किक त्रुटि का संकेत दे सकता है। उदाहरण के लिए, तर्क को whileकहीं और परिभाषित किया जा सकता है और आपको यह महसूस नहीं होता कि यह स्थिर है।


2

मुझे आश्चर्य है कि किसी ने भी वांछित विधानसभा के अनुरूप अधिक प्रत्यक्ष रूप की पेशकश नहीं की है:

forever:
     do stuff;
     goto forever;

खुराक जो 1 के रूप में एक ही मशीन कोड के साथ समाप्त नहीं होती है या सी (;) के लिए सी कहती है?
कोपा

1
उस दृष्टिकोण की एक और कमी: यह एक ब्लॉक में लूप को संलग्न न करके एनकैप्सुलेशन का उल्लंघन करता है - इस प्रकार लूप में घोषित कोई भी चर लूप के बाहर उपलब्ध होता है। (ज़ाहिर है, आप कर सकते हैं { forever: do stuff; goto forever; })
रॉय टिंकर

2

while(1)एक मुहावरा है for(;;)जिसके लिए अधिकांश संकलक द्वारा मान्यता प्राप्त है।

मुझे यह देखकर खुशी हुई कि पर्ल until(0)भी पहचानता है।


किस स्थिति में (0) सहायक होगा?
कोपस 18

3
जब तक (), जबकि () के विपरीत है, जब तक () अगर () के विपरीत है। जैसा कि इस सूत्र में बताया गया है, कोई भी लिख सकता है: {कुछ ...} करें जबकि (स्थिति) एक विकल्प तब तक हो सकता है जब तक (स्थिति) {कुछ}
जेएमडी

2

for (;;)बनाम while (1)बहस को सारांशित करने के लिए यह स्पष्ट है कि पुराने पुराने गैर-अनुकूलन वाले संकलक के दिनों में तेज था, यही कारण है कि आप इसे पुराने कोड बेस में देखते हैं जैसे लायंस यूनिक्स सोर्स कोड कमेंट्री, हालांकि बदमाश अनुकूलन की उम्र में संकलक उन लाभों को दूर युग्मन से अनुकूलित किया जाता है कि इस तथ्य के साथ कि बाद वाला पूर्व की तुलना में समझना आसान है, मेरा मानना ​​है कि यह अधिक बेहतर होगा।


2

बस इस धागे के पार आया (हालांकि काफी कुछ साल देर से)।

मुझे लगता है कि मैंने वास्तविक कारण पाया कि "के लिए (?;)" "(1)" से बेहतर है।

"बर्र कोडिंग मानक 2018" के अनुसार

Kernighan & Ritchie long ago recommended for (;;) , which has the additional benefit
of insuring against the visually-confusing defect of a while (l); referencing a variable l’.

मूल रूप से, यह गति का मुद्दा नहीं है बल्कि पठनीयता का मुद्दा है। कोड के फॉन्ट / प्रिंट के आधार पर नंबर एक (1) थोड़ी देर में कम केस लेटर की तरह लग सकता है।

यानी 1 बनाम एल। (कुछ फोंट में ये समान दिखते हैं)।

तो जबकि (1) कुछ ऐसा लग सकता है जबकि लूप चर अक्षर L पर निर्भर है।

जबकि (सच्चा) भी काम कर सकता है लेकिन कुछ पुराने C और एम्बेडेड C मामलों में सच / गलत को तब तक परिभाषित नहीं किया जाता है जब तक कि stdbool.h को शामिल नहीं किया जाता है।


2
मैं कहूंगा कि आपके कोड में मुद्दा यह होगा कि आपके पास नाम का एक चर है l, न कि यह 1और lसमान दिख सकता है।
मज्पोपरि

सहमत, मैं जानता हूं कि बर्र कोडिंग मानक भी कहीं और कहता है कि लूप के लिए चर भी कम से कम 3 वर्ण होने चाहिए। यानी लूप के लिए i i ++ आदि। मुझे लगता है कि हालांकि थोड़ा बहुत हो सकता है। टाइप करते समय मैं यह भी सूचित कर रहा हूं कि यह केवल L जैसा दिखने वाला अक्षर L नहीं है। 1. वह पत्र जिसे आमतौर पर एक चर के रूप में उपयोग किया जाता है, यह भी समस्या हो सकती है।
निक लॉ

-3

मुझे लगता है कि प्रदर्शन के मामले में दोनों समान हैं। लेकिन मैं पठनीयता के लिए (1) पसंद करूंगा लेकिन मुझे सवाल है कि आपको अनंत लूप की आवश्यकता क्यों है।


-14

वह एक जैसे है। विचार करने के लिए बहुत अधिक महत्वपूर्ण प्रश्न हैं।


मेरा बिंदु जो निहित था लेकिन स्पष्ट रूप से ऊपर नहीं बनाया गया है, यह है कि एक सभ्य संकलक दोनों लूप रूपों के लिए समान कोड उत्पन्न करेगा। इससे भी बड़ी बात यह है कि लूपिंग कंस्ट्रक्शन किसी भी एल्गोरिदम के रन टाइम का एक मामूली हिस्सा है, और आपको पहले यह सुनिश्चित करना होगा कि आपने एल्गोरिथम और उससे जुड़ी बाकी सभी चीजों को ऑप्टिमाइज़ किया है। आपके लूप निर्माण का अनुकूलन आपकी प्राथमिकता सूची में सबसे नीचे होना चाहिए।


22
कोई लिंक या स्पष्टीकरण नहीं। निष्कलंक, व्यक्तिपरक और थोड़ा कृपालु।
cdmckay

1
कोई सबूत नहीं लेकिन वह सही है। वे दोनों झूठे होने पर कूदने के लिए ओपकोड कहते हैं। (जो इसे गोटो जैसा ही बना लेगा लेकिन किसी को गोटो पसंद नहीं है)
मैथ्यू

3
मैं इस बात से अनजान था कि केवल महत्वपूर्ण प्रश्न जहाँ पूछे जाएँ, मेरी गलती मेरा पहला प्रश्न था।
कोपा

3
हां, मैं मानता हूं कि यह कृपालु है। लेकिन गंभीरता से, यहां तक ​​कि किसी भी सबूत के बिना यह स्पष्ट है कि वे एक ही बॉलपार्क गति में होने जा रहे हैं; अगर सवाल शैली के बारे में था तो बहस करने के लिए कुछ होगा। मैं इस बात को बनाने की कोशिश कर रहा था कि चीजों की सूची के बारे में चिंता करने के लिए, यह वास्तव में सूची में सबसे नीचे होना चाहिए।
मार्क रैनसम

8
मैं एक झटका बनने की कोशिश नहीं कर रहा था। मैं एक बिंदु बनाने की कोशिश कर रहा था। जब मैंने इसे पोस्ट किया तो मैं एक प्रकार के अंधेरे हास्य के लिए कोशिश कर रहा था, और यह स्पष्ट है कि मैं असफल रहा; इसके लिए मैं माफी चाहता हूं।
मार्क रैनसम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.