2011-09-05 6 views
7

सी # में conditional operator और IF कथन हैं और मुझे संदेह है कि सशर्त ऑपरेटर केवल वाक्य रचनात्मक चीनी होगा। तो संकलन समय पर यह एक आईएफ ऑपरेशन के समान होगा।आईएफ और सशर्त ऑपरेटर के बीच आईएल में इतना अंतर क्यों है?

हालांकि वे नहीं देखते हैं (नीचे देखें), उनके पास अलग-अलग आईएल हैं। मेरे सिर को इसके चारों ओर लपेटने की कोशिश कर रहा है और मेरे पास धारणा है कि यह एक प्रदर्शन अनुकूलन है कि सशर्त ऑपरेटर इसलिए प्राप्त होता है क्योंकि यह सीमित दायरा है।

जानना चाहते हैं कि मेरी धारणा सही है या नहीं और शायद इसके लिए और भी कुछ है?

आईएफ के आईएल में भी कुछ मूल्यों (L_000c, L_000d, L_000f) int मूल्यों के आस-पास हैं जिन्हें मैं अर्थ नहीं समझ सकता। यही कारण है कि मुझे लगता है कि यह अधिक मजबूत समाधान के कारण प्रदर्शन की लागत पर एक और मजबूत समाधान है।


कोड यदि

var result = ""; 
if (Environment.Is64BitOperatingSystem) 
{ 
    result = "Yes"; 
} 
else 
{ 
    result = "No"; 
} 
Console.WriteLine(result); 

कोड सशर्त ऑपरेटर के लिए के लिए -

Console.WriteLine("Is the OS x64? {0}", Environment.Is64BitOperatingSystem ? "Yes" : "No"); 
(मैं मतभेद का एहसास है, लेकिन कोई फर्क नहीं पड़ता कि कैसे मैं इसे बदल चर आदि के लिए असाइन ... यह बहुत कम फर्क नहीं पड़ता)

आईएल यदि

L_0001: ldstr "" 
L_0006: stloc.0 
L_0007: call bool [mscorlib]System.Environment::get_Is64BitOperatingSystem() 
L_000c: ldc.i4.0 
L_000d: ceq 
L_000f: stloc.2 
L_0010: ldloc.2 
L_0011: brtrue.s L_001d 
L_0013: nop 
L_0014: ldstr "Yes" 
L_0019: stloc.0 
L_001a: nop 
L_001b: br.s L_0025 
L_001d: nop 
L_001e: ldstr "No" 
L_0023: stloc.0 
L_0024: nop 
L_0025: ldloc.0 
L_0026: call void [mscorlib]System.Console::WriteLine(string) 

आईएल च के लिए या सशर्त

L_002c: ldstr "Is the OS x64? {0}" 
L_0031: call bool [mscorlib]System.Environment::get_Is64BitOperatingSystem() 
L_0036: brtrue.s L_003f 
L_0038: ldstr "No" 
L_003d: br.s L_0044 
L_003f: ldstr "Yes" 
L_0044: call void [mscorlib]System.Console::WriteLine(string, object) 
+3

बस यह सुनिश्चित करने के लिए: क्या आप रिलीज मोड में संकलित हैं (एनओपी इसे पहली नज़र में डीबग मोड की तरह दिखते हैं)? डीबग मोड में, कंपाइलर डीबगिंग को आसान बनाने के लिए सभी अनुकूलन नहीं करता है। –

+1

क्या यह डीबग या रिलीज़ मोड है? जहां तक ​​मुझे पता है, छेड़छाड़ के लिए 'एनओपी' का उपयोग किया जाता है। –

+1

दोनों रिहाई मोड में हैं? –

उत्तर

6

अगर

IL_0000: call  bool [mscorlib]System.Environment::get_Is64BitOperatingSystem() 
IL_0005: brfalse.s IL_000f 
IL_0007: ldstr  "Yes" 
IL_000c: stloc.0     // <------ Difference 1 
IL_000d: br.s  IL_0015 
IL_000f: ldstr  "No" 
IL_0014: stloc.0 
IL_0015: ldloc.0 
IL_0016: call  void [mscorlib]System.Console::WriteLine(string) 

? (त्रिगुट ऑपरेटर)

IL_001b: call  bool [mscorlib]System.Environment::get_Is64BitOperatingSystem() 
IL_0020: brtrue.s IL_0029 
IL_0022: ldstr  "No"   // <------ Difference 2 
IL_0027: br.s  IL_002e 
IL_0029: ldstr  "Yes" 
IL_002e: stloc.0 
IL_002f: ldloc.0 
IL_0030: call  void [mscorlib]System.Console::WriteLine(string) 

(लगभग) एक ही दोनों के लिए रिलीज़ मोड में कोड। if एक दूसरा stdloc.0 जोड़ता है जिसे संकलक द्वारा अनुकूलित नहीं किया गया है। और दूसरा अंतर यह है कि true और false उलटा हुआ है।

(तो मैं समझ जाते हैं कि मैं हमेशा WinMerge ऊपर सक्रिय किया जाना चाहिए!)

और यह एक दिलचस्प सवाल होगा। वे उलटे क्यों हैं? क्या कोई तर्क है?

+0

यिप, अच्छी तरह से देखा। मुद्दा रिलीज मोड बनाम डीबग मोड है। –

+2

आप कहते हैं "केवल अंतर", लेकिन निश्चित रूप से, 'में?'मामला,' 001b'-'0029' सशर्त अभिव्यक्ति के * मान * की गणना कर रहे हैं, और फिर अंत में इसे '002e' पर एक चर के लिए असाइन किया गया है, जबकि यदि कथन के तहत, दो संभावित असाइनमेंट हैं ('000c' और '0014'), जो निश्चित रूप से असंबंधित चर के लिए हो सकता है, और 'if' कथन * मान नहीं है। –

+0

@Damien_The_Unbeliever दाएं। सही किया। यह मुझे सिखाता है कि WinMerge प्रोग्रामर का सबसे अच्छा दोस्त है :-) – xanatos

संबंधित मुद्दे