2009-11-10 9 views
37

यह सुनिश्चित करने के बाहर कि उन्हें बदला नहीं जा सकता (एक कंपाइलर त्रुटि की धुन के लिए), क्या जेआईटी कॉन्स स्थानीय लोगों के लिए कोई अनुकूलन करता है?क्या स्थानीय स्थानीय चर का उपयोग करने के लिए कोई रनटाइम लाभ है?

ईजी।

public static int Main(string[] args) 
{ 
    const int timesToLoop = 50; 

    for (int i=0; i<timesToLoop; i++) 
    { 
     // ... 
    } 
} 
+3

रनटाइम लाभ? मेरा झुकाव यह शायद अधिक कुशल होना चाहिए हालांकि शायद महत्वहीन है। जवाब का उत्सुक भी हूं। –

+0

चूंकि यह संकलन-समय अनुकूलन के परिणामस्वरूप होने की संभावना है, मुझे संदेह होगा कि इसे वैश्विक आधार जैसे ही अनुकूलित किया गया था। – Lazarus

+0

मुझे एहसास है कि कोई भी अनुकूलन महत्वहीन होगा, यह एक जिज्ञासा प्रश्न था :) –

उत्तर

70

उत्पन्न आईएल अलग (रिलीज़ मोड का उपयोग) है: आप देख सकते हैं संकलक निरंतर जो एक छोटे ढेर में जो परिणाम के मान से सभी चर प्रयोगों की जगह

using constant local     using normal local 
--------------------------------------------------------------------- 
.entrypoint       .entrypoint 
.maxstack 2       .maxstack 2 
.locals init (      .locals init (
    [0] int32 i)       [0] int32 timesToLoop, 
L_0000: ldc.i4.0       [1] int32 i) 
L_0001: stloc.0      L_0000: ldc.i4.s 50 
L_0002: br.s L_0008     L_0002: stloc.0 
L_0004: ldloc.0      L_0003: ldc.i4.0 
L_0005: ldc.i4.1      L_0004: stloc.1 
L_0006: add       L_0005: br.s L_000b 
L_0007: stloc.0      L_0007: ldloc.1 
L_0008: ldloc.0      L_0008: ldc.i4.1 
L_0009: ldc.i4.s 50     L_0009: add 
L_000b: blt.s L_0004     L_000a: stloc.1 
L_000d: ret       L_000b: ldloc.1 
             L_000c: ldloc.0 
             L_000d: blt.s L_0007 
             L_000f: ret 

+20

+1! – MagicAndi

+0

एक छोटे से छोटे ढेर के अलावा, यह कार्यात्मक रूप से वही है। हालांकि दिलचस्प है। – kenny

+2

महान उत्तर, और अच्छी तरह से स्वरूपित! –

3

यह कहीं भी एक जवाब के पास नहीं है, बस सोचा था कि यह साझा करने के लिए इस तथापि लेख स्पष्ट रूप से क्रम लाभ का उल्लेख नहीं है अच्छा होगा:
Coding Standard Rule #2: Use const Wherever Possible

अंश:
तर्क: का उपयोग करने का उल्टा यथासंभव कॉन्सलर-लागू बल अनचाहे लिखने वाले डेटा से डेटा को केवल पढ़ने के लिए किया जाना चाहिए।

0

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

+3

प्रश्न कांस्टल स्थानीय लोगों को संदर्भित करता है, न कि फ़ील्ड/सदस्यों को। –

5

आपका कोड (स्थिरांक का प्रयोग करके) वास्तव में के रूप में संकलित किया जाएगा:

public static int Main(string[] args){  
    for (int i=0; i < 50; i++) 
    { 

    } 
} 

जबकि एक चर एक चर के रूप में संकलित कर देगा:

public static int Main(string[] args){ 
    int timesToLoop = 50;  
    for (int i=0; i < timesToLoop; i++) 
    { 

    } 
} 
10

मैं कोड एक त्वरित प्रदर्शन परीक्षण दिया था, Snippet Compiler का उपयोग कर ।

public static void Main() 
    { 
     DateTime datStart = DateTime.UtcNow; 
     const int timesToLoop = 1000000; 

     for (int i=0; i < timesToLoop; i++) 
     { 
      WL("Line Number " + i.ToString()); 
     } 

     DateTime datEnd = DateTime.UtcNow; 
     TimeSpan tsTimeTaken = datEnd - datStart; 
     WL("Time Taken: " + tsTimeTaken.TotalSeconds); 
     RL(); 
    } 

ध्यान दें, WL और आर एल बस सहायक तरीकों पढ़ सकते हैं और कंसोल के लिए लिखने के लिए कर रहे हैं: कोड मैं का इस्तेमाल किया इस प्रकार है।

गैर-निरंतर संस्करण का परीक्षण करने के लिए, मैंने बस const कीवर्ड हटा दिया। परिणाम आश्चर्यजनक थे:

     Time Taken (average of 3 runs) 

Using const keyword   26.340s 
Without const keyword  28.276s 

मुझे पता है कि यह बहुत ही rough'n'ready परीक्षण है हूँ, लेकिन const कीवर्ड के उपयोग के लिए एक वैध micro-optimization के रूप में गिनती करने के लिए प्रकट होता है।

+14

माइक्रो-ऑप्टिमाइज़ेशन के बारे में बात करते हुए, आपको 'डेटटाइम.अब' के बजाय 'डेटटाइम.यूटीसीएनओ' का उपयोग करना चाहिए क्योंकि पूर्व को ओएस से स्थानीय टाइमज़ोन के लुकअप की आवश्यकता नहीं होती है। –

+0

रिचर्ड, धन्यवाद, एक नई टिप! – MagicAndi

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