अगर मैं जावा में लूप के अंदर या बाहर चर घोषित करता हूं तो क्या इससे कोई फर्क पड़ता है? [बन्द है]


13

संभव डुप्लिकेट:
आप चर कहां घोषित करते हैं? एक विधि का शीर्ष या जब आपको उनकी आवश्यकता होती है?

अगर मैं जावा में लूप के अंदर या बाहर चर घोषित करता हूं तो क्या इससे कोई फर्क पड़ता है?

क्या इस

for(int i = 0; i < 1000; i++) {
   int temp = doSomething();
   someMethod(temp);
}

इसके बराबर (स्मृति उपयोग के संबंध में)?

int temp = 0;
for(int i = 0; i < 1000; i++) {
   temp = doSomething();
   someMethod(temp);
}

और क्या होगा अगर अस्थायी चर एक ArrayList उदाहरण के लिए है?

for(int i = 0; i < 1000; i++) {
   ArrayList<Integer> array = new ArrayList<Integer>();
   fillArray(array);
   // do something with the array
}

संपादित करें: javap -cमैं निम्नलिखित उत्पादन मिला है

लूप के बाहर चर:

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0      
       1: istore_1      
       2: iconst_0      
       3: istore_2      
       4: iload_2       
       5: sipush        1000
       8: if_icmpge     25
      11: invokestatic  #2                  // Method doSomething:()I
      14: istore_1      
      15: iload_1       
      16: invokestatic  #3                  // Method someMethod:(I)V
      19: iinc          2, 1
      22: goto          4
      25: return  

लूप के अंदर चर:

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0      
       1: istore_1      
       2: iload_1       
       3: sipush        1000
       6: if_icmpge     23
       9: invokestatic  #2                  // Method doSomething:()I
      12: istore_2      
      13: iload_2       
      14: invokestatic  #3                  // Method someMethod:(I)V
      17: iinc          1, 1
      20: goto          2
      23: return        

और रुचि के लिए, यह कोड:

public class Test3 {
    public static void main(String[] args) {
        for(int i = 0; i< 1000; i++) {
            someMethod(doSomething());
        }   
    }
    private static int doSomething() {
        return 1;
    }
    private static void someMethod(int temp) {
        temp++;
    }
}

इसका उत्पादन करता है:

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0      
       1: istore_1      
       2: iload_1       
       3: sipush        1000
       6: if_icmpge     21
       9: invokestatic  #2                  // Method doSomething:()I
      12: invokestatic  #3                  // Method someMethod:(I)V
      15: iinc          1, 1
      18: goto          2
      21: return   

लेकिन अनुकूलन तब रनटाइम पर होता है। क्या अनुकूलित कोड को देखने का कोई तरीका है? (लंबे EDIT के लिए क्षमा करें)


1
मुझे खुशी है कि आपने वास्तव में असंतुष्टता को देखा और आशा है कि यह आपको कुछ सिखाएगा। मुझे उम्मीद थी कि वास्तविक जावा अनुभव वाले किसी व्यक्ति को अनुकूलित कोड के बारे में आपके अंतिम प्रश्न का उत्तर मिलेगा, लेकिन शायद आप उस विशिष्ट भाग को स्टैकओवरफ़्लो पर पोस्ट कर सकते हैं - यह एक बहुत ही ठोस प्रश्न लगता है।
जोरिस टिम्मरमन्स

हां, मैं अनुकूलित कोड प्राप्त करने का प्रयास करूंगा। (सवाल थोड़ा बदला, मैंने एडिट में ऑप्टिमाइज़्ड कोड वाली बात
पूछी

डुप्लिकेट पर टूटी हुई कड़ी। इस प्रश्न को एक मूल बनाने का समय आ गया है।
जोन

जवाबों:


4

इन प्रश्नों में से अधिकांश का सामान्य उत्तर होना चाहिए "आप इसे क्यों आजमाते हैं और पता नहीं लगाते हैं?"। जावा में आप शायद उत्पन्न बाइटकोड पर एक नज़र डाल सकते हैं (मेरा मानना ​​है कि उपकरण को जावप कहा जाता है), यह देखने के लिए कि बाइट कोड में क्या अंतर है चर घोषित करने के उन दो तरीकों के बीच।

ऐसा करना आपके लिए एक बेहतर सीखने का अनुभव है, क्योंकि अगली बार जब आप एक अनुकूलन समस्या में चल रहे होते हैं, तो आप यह सत्यापित करने के लिए एक ही टूल का उपयोग कर सकते हैं कि कंपाइलर वह कर रहा है जो आप उम्मीद कर रहे हैं - यह आपको अनावश्यक रूप से अपना कोडिंग बदलने से बचने में मदद करेगा शैली जब ऑप्टिमाइज़र अपने आप ठीक होता है, या जब आप वास्तव में उस प्रदर्शन के अंतिम बिट की आवश्यकता होती है, तो वास्तविक ट्वीक ढूंढते हैं।


3

संक्षिप्त उत्तर: नहीं। इस साइट पर पहले से ही समान प्रश्न थे। उत्पन्न बायोटेक के अनुसार कोई उल्लेखनीय अंतर नहीं है। जरूरत पड़ने पर उन्हें घोषित करना कोड की कम लाइनें पैदा करता है

यहां स्वीकृत उत्तर है: /software//a/56590/43451


प्रदर्शन के बारे में क्या जब आप लूप के अंदर एक नई वस्तु बनाते हैं, तो वह केवल एक बार ही बनाया जा सकता है?
बबलप्रेप

3
इस मामले में स्पष्ट रूप से प्रदर्शन और स्मृति दंड है। लेकिन यह ऑप के सवाल में काफी नहीं है
केमोडा

1
लिंक टूट गया है।
जोन

1

व्यक्तिगत चर के स्तर पर प्रभाव में कोई महत्वपूर्ण अंतर नहीं है, लेकिन अगर आपके पास 1000 लूप और 1000 चर (कभी भी खराब शैली का बुरा न मानें) के साथ एक समारोह था, तो प्रणालीगत अंतर हो सकता है क्योंकि सभी चर के सभी जीवन होंगे ओवरलैप की बजाय वही। यह स्टैक आकार और कचरा संग्रहकर्ता की चर को साफ करने की क्षमता को प्रभावित कर सकता है जो कि आवश्यकता से अधिक समय तक जीवित रखा जा रहा था।

इसके अलावा, चर को सबसे छोटी संभव गुंजाइश देने के लिए यह बेहतर शैली है। यह दुर्घटनाओं को रोकता है।


यह सच नहीं है - जेवीएम स्तर पर, स्थानीय चर के लिए सीमित गुंजाइश जैसी कोई चीज नहीं है।
माइकल बोर्गवर्ड्ट

क्या आपका मतलब है कि अगर मैं 1000 बार (int i = ..) लिखता हूं, तो फ़ंक्शन से बाहर निकलने पर स्टैक पर 1000 अलग-अलग चर होंगे?
ddyer

Artima.com/insidejvm/ed2/jvm8.html के अनुसार "उदाहरण के लिए, यदि दो स्थानीय चरों में सीमित दायरे होते हैं जो ओवरलैप नहीं करते हैं, जैसे कि उदाहरण 3b में i और j स्थानीय चर, संकलन समान सरणी प्रविष्टि का उपयोग करने के लिए स्वतंत्र हैं दोनों चर के लिए। "और यह केवल समझ में आता है, कंपाइलर इस तरह से स्टैक फ्रेम के आकार को अनुकूलित करने के लिए स्वतंत्र हैं।
ddyer

1
अच्छी बात; लेकिन अगर हम कंपाइलर ऑप्टिमाइज़ेशन के बारे में बात कर रहे हैं, तो कंपाइलर लगभग वैरिएबल वैरिएबल एंट्रीज़ को आसानी से दोबारा इस्तेमाल कर सकते हैं, जिनमें लेक्सिकल स्कोप ओवरलैपिंग है लेकिन ओवरलैपिंग तरीके से इसका इस्तेमाल नहीं किया जाता है।
माइकल Borgwardt
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.