2010-07-27 8 views
17

वाक्य रचना मैं देख रहा हूँ कि वे पाश को अनिश्चित काल के एक ब्रेक बयान तक पहुँच जाता है, लेकिन वे एक ही बात करने के लिए संकलित कर रहे हैं? क्या थोड़ा तेज़ है क्योंकि इसकी जांच करने की कोई शर्त नहीं है? कोड पठनीयता के अलावा, क्या कोई अंतर भी है?अंतर है?

+0

देखें http://stackoverflow.com/questions/2288856/when-implementing-an-infinite-loop-is-there-a-difference-in-using-while1-vs-fo –

+0

यह एक अच्छा सवाल है। मुझे यह देखना दिलचस्प लगता है कि संकलक कोड को नीचे करने के लिए अनुकूलित करता है जबकि उदाहरण कोड में लूप ने इसे आजमाया। –

+1

'के लिए (;;)' ए है) पूर्व सी कोडर्स द्वारा लिखित, और बी) चार वर्ण छोटे :) – hobbs

उत्तर

36

इस इनपुट को देखते हुए:

private static void ForLoop() 
{ 
    int n = 0; 
    for (; ;) 
    { 
     Console.WriteLine(n++); 
    } 
} 

private static void WhileLoop() 
{ 
    int n = 0; 
    while (true) 
    { 
     Console.WriteLine(n++); 
    } 
} 

... आप इस आउटपुट प्राप्त:

.method private hidebysig static void ForLoop() cil managed 
{ 
    // Code size  14 (0xe) 
    .maxstack 3 
    .locals init ([0] int32 n) 
    IL_0000: ldc.i4.0 
    IL_0001: stloc.0 
    IL_0002: ldloc.0 
    IL_0003: dup 
    IL_0004: ldc.i4.1 
    IL_0005: add 
    IL_0006: stloc.0 
    IL_0007: call  void [mscorlib]System.Console::WriteLine(int32) 
    IL_000c: br.s  IL_0002 
} // end of method Program::ForLoop 


.method private hidebysig static void WhileLoop() cil managed 
{ 
    // Code size  14 (0xe) 
    .maxstack 3 
    .locals init ([0] int32 n) 
    IL_0000: ldc.i4.0 
    IL_0001: stloc.0 
    IL_0002: ldloc.0 
    IL_0003: dup 
    IL_0004: ldc.i4.1 
    IL_0005: add 
    IL_0006: stloc.0 
    IL_0007: call  void [mscorlib]System.Console::WriteLine(int32) 
    IL_000c: br.s  IL_0002 
} // end of method Program::WhileLoop 

उल्लेखनीय समान, मैं कहूंगा कि (समान, यहां तक ​​कि)।

+0

में है जब तक कि मुझे कुछ याद नहीं आ रहा है, वे टिप्पणियों और पहचानकर्ता नामों के बाहर * समान * हैं। –

+0

@ टी.ई.डी. हाँ, वे समान हैं। –

+18

हम्म, लाइन 5 पर एक अंतर है ... ओह, रुको, नहीं, यह मेरी मॉनिटर पर एक जगह है;) –

2

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

एक अन्य की तुलना में तेजी है, तो सी # संकलक लेखकों कुछ चाहिए 'उन्हें splained ...

21

आधुनिक compilers, बिल्कुल कुछ भी नहीं है।

ऐतिहासिक रूप से, हालांकि, for(;;) को एक ही कूद के रूप में लागू किया गया था, जबकि while(true) भी सच के लिए एक जांच थी।

मैं while(true) पसंद करता हूं, क्योंकि इससे यह स्पष्ट हो जाता है कि मैं क्या कर रहा हूं।

+2

+1 बिल्कुल। 'जबकि (सत्य)' '(;;)' के लिए 'से अधिक स्पष्ट है। मैं किसके लिए इंतजार कर रहा हूं, वैसे भी? –

+1

मैं दिल से सहमत हूं कि आपको वह व्यक्ति चुनना चाहिए जो आपको लगता है कि स्पष्ट है, हालांकि मैं इस बात से असहमत हूं कि कौन सा है ... –

+2

क्यों नहीं 'लूप: ... गोटो लूप'? –

0

वे एक ही चीज़ को संकलित करते हैं। आप एक परीक्षण एप्लिकेशन कि दोनों तरीकों को लागू करता है लिखना और फिर पुष्टि करने के लिए वे आईएल समान है ILDASM उपयोग कर सकते हैं।

+3

या आप केवल फ्रेड्रिक के जवाब को देख सकते हैं और खुद को परेशानी बचा सकते हैं। :) – DarLom

0

एक डीबग असेंबली (सत्य) का पालन करता है। परावर्तक का प्रयोग करें और आप परिणाम देख सकते हैं।

static void Main(string[] args) 
    { 
     ExecuteWhile(); 

     ExecuteFor(); 
    } 

    private static void ExecuteFor() 
    { 
     for (; ;) 
     { 
      Console.WriteLine("for"); 
      string val = Console.ReadLine(); 
      if (string.IsNullOrEmpty(val)) 
      { 
       Console.WriteLine("Exit for."); 
       break; 
      } 
     } 
    } 

    private static void ExecuteWhile() 
    { 
     while (true) 
     { 
      Console.WriteLine("while"); 
      string val = Console.ReadLine(); 
      if (string.IsNullOrEmpty(val)) 
      { 
       Console.WriteLine("Exit while."); 
       break; 
      } 
     } 
    } 

परावर्तक में ExecuteFor विधि का निरीक्षण करना।

private static void ExecuteFor() 
{ 
    while (true) 
    { 
     Console.WriteLine("for"); 
     if (string.IsNullOrEmpty(Console.ReadLine())) 
     { 
      Console.WriteLine("Exit for."); 
      return; 
     } 
    } 
} 

एक ही कोड का एक अनुकूलित संस्करण यहाँ शब्दाडंबर के लिए के लिए ExecuteFor

private static void ExecuteFor() 
{ 
    do 
    { 
     Console.WriteLine("for"); 
    } 
    while (!string.IsNullOrEmpty(Console.ReadLine())); 
    Console.WriteLine("Exit for."); 
} 

अलग परिणाम का उत्पादन अनुकूलित ExecuteWhile है ...

private static void ExecuteWhile() 
{ 
    do 
    { 
     Console.WriteLine("while"); 
    } 
    while (!string.IsNullOrEmpty(Console.ReadLine())); 
    Console.WriteLine("Exit while."); 
} 
+0

क्या यह वास्तव में 'सत्य (सत्य)' तक संकलित करता है, या क्या प्रतिबिंबक इस तरह से इसे संकलित करता है? : पी –

+0

यदि आप एक ही असेंबली से बनाए गए आईएल को देखते हैं तो यह उस तरह से पढ़ता है। –

0

के रूप में किसी के साथ, दूसरों के द्वारा उल्लेख किया आधुनिक कंपाइलर, यह बिल्कुल कोई फर्क नहीं पड़ता है।

मैंने अपने कंप्यूटर पर एक संक्षिप्त परीक्षण किया, एक या दूसरे का उपयोग करके कुछ संचालन का समय लगाया, और वे हमेशा एक ही समय में काफी अधिक लेते थे। बेशक, अन्य प्रक्रियाओं चल रहा है की वजह से, इन परीक्षणों नहीं 100% सही हैं, लेकिन अगर वहाँ गति में अंतर होता है (वहाँ नहीं होना चाहिए) तो यह एक सूक्ष्म से एक है।

1

यदि मैं कर सकता हूं, तो मैं सुझाव दूंगा कि आप कुछ अलग सवाल देखेंगे। यदि आप इनमें से किसी एक का उपयोग अक्सर देखभाल करने के लिए पर्याप्त कर रहे हैं, तो आप शायद अपने कोड को खराब तरीके से बना रहे हैं। हालांकि एम्बेडेड सिस्टम जैसी चीजें हैं जो वास्तव में हमेशा के लिए चलती हैं, अधिकांश सामान्य कोड में लूप नहीं होते हैं। कि दावों हमेशा के लिए चलाने के लिए एक पाश लेखन आम तौर पर आप कुछ अन्य नियंत्रण प्रवाह के साथ पाश के लिए बाहर निकलने के हालत द्वारा छिपाए गए कहीं अंदर, इसका मतलब है (उदाहरण के लिए, if (whatever) break;) वास्तविक लूप से बाहर निकलने के रूप में।

जो कि आमतौर पर टाला जा सकता है। हालाँकि ऐसी स्थितियां हैं जहां break बयान समझ में आता है, उन्हें आम तौर पर असामान्य स्थितियों को संभालना चाहिए, एक लूप लिखने के लिए नहीं, जो एक बात कहता है लेकिन दूसरा करता है (यानी, "हमेशा के लिए दौड़ता है", लेकिन वास्तव में "स्थिति पूरी होने तक चलती है")।

+0

मैं इस से सहमत नहीं हो सकता। –

+0

मुझे न तो। जब मैं पहली बार पीएल/आई में प्रोग्राम करना सीख रहा था (मुझे नहीं पता कि इसमें 'ब्रेक' कथन भी था) पैटर्न "फ़ाइल की पढ़ी रेखा" थी, जबकि यह एंड-मार्कर नहीं है, लूप करें, जो समाप्त होता है अगली पंक्ति पढ़ने के साथ "। ऐसा लगता है कि "खुद को दोहराएं" का उल्लंघन। मैं सुझाव दूंगा कि लूप की शुरुआत में एक बार लाइन को पढ़ना, और अगर यह एक एंड-मार्कर है तो बाहर निकलना बेहतर शैली है। – supercat

+0

@supercat: मैं सहमत हूं, लेकिन यह कुछ भी उचित नहीं है। आपको 'file (get.getline())', '(;;) के लिए नहीं होना चाहिए (! File.getline()) तोड़ें;' –