दिलचस्प पोस्ट
पायथन में फ़ाइल निर्माण और संशोधन तिथि / बार कैसे प्राप्त करें? टी-एसक्यूएल में पिवट डेटा नेविगेशनदृश्य के लिए पाद लेख कैसे जोड़ें – एंड्रॉइड सपोर्ट डिज़ाइन लाइब्रेरी? चेक करें कि क्या कुकी सक्षम हैं PHP घातक त्रुटि: अपरिभाषित फ़ंक्शन json_decode () को कॉल करें गिटग्नॉर फ़ाइल में पथ में अंतर? पाठ क्षेत्र में jQuery सेट कर्सर स्थिति लेबल को हाइलाइट करें अगर चेकबॉक्स को चेक किया गया हो Chrome में मॉनिटरिंग का अनुरोध करें सी प्रोग्रामिंग भाषा में ईओएफ क्या है? रूबी में प्रतीकों को कैसे समझें सी + +: लाँगजम्प और सेटजेम्प का उपयोग करने के लिए सुरक्षित? एंड्रॉइड कूड़ा कलेक्टर के तकनीकी विवरण कोणीय UI राउटर: माता-पिता निराधार ऑब्जेक्ट के आधार पर बाल राज्य टेम्पलेट तय करें यह कोड कॉपी कन्स्ट्रक्टर को कॉल करने का प्रयास क्यों कर रहा है?

कौन सा पाश बेहतर प्रदर्शन है? क्यूं कर?

String s = ""; for(i=0;i<....){ s = some Assignment; } 

या

 for(i=0;i<..){ String s = some Assignment; } 

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

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

इसके अलावा, सवाल यह नहीं है कि मैं स्मृति प्रबंधन के बारे में चिंतित हूं। बस जानना चाहते हैं कि कौन सा बेहतर है

वेब के समाधान से एकत्रित समाधान "कौन सा पाश बेहतर प्रदर्शन है? क्यूं कर?"

सीमित स्कोप सर्वोत्तम है

अपना दूसरा विकल्प उपयोग करें:

 for ( ... ) { String s = ...; } 

क्षेत्र प्रदर्शन पर प्रभाव नहीं पड़ता

यदि आप प्रत्येक से संकलित कोड को अलग करते हैं ( javap के javap उपकरण के साथ), तो आप देखेंगे कि लूप दोनों ही मामलों में सटीक एक ही जेवीएम निर्देशों के लिए संकलित है। यह भी ध्यान रखें कि ब्रायन आर। बॉन्डी का "विकल्प # 3" विकल्प # 1 के समान है कठोर दायरे का उपयोग करते समय स्टैक से कोई भी अतिरिक्त जोड़ा या निकाला नहीं जाता है, और दोनों ही मामलों में स्टैक पर समान डेटा का उपयोग किया जाता है।

समयपूर्व आरंभ से बचें

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

आप इसे खाली घोषणा (यानी String s; ) का उपयोग करके इसे ठीक कर सकते हैं, लेकिन यह बुरा व्यवहार माना जाता है और इसके नीचे एक अन्य साइड इफेक्ट पर चर्चा की गई है।

अक्सर एक नकली मूल्य जैसे null को एक परिवर्तनीय त्रुटि को एक कम्पाइलर त्रुटि को छूने के लिए सौंपा जाता है जो कि एक चर को आरम्भ किए बिना पढ़ा जाता है। यह त्रुटि एक संकेत के रूप में ली जा सकती है कि चर गुंजाइश बहुत बड़ी है, और यह मान्य मान प्राप्त करने के लिए आवश्यक होने से पहले इसे घोषित किया जा रहा है। खाली घोषणाएं आपको हर कोड पथ पर विचार करने के लिए प्रेरित करती हैं; एक फर्जी मान निर्दिष्ट करके इस मूल्यवान चेतावनी को अनदेखा न करें।

स्टेक स्लॉट का संरक्षण करें

जैसा कि उल्लेख किया गया है, जबकि दोनों स्थितियों में जेवीएम निर्देश समान हैं, एक सूक्ष्म साइड-इफेक्ट होता है, जो कि जेवीएम स्तर पर सबसे ज्यादा सीमित अवसर का उपयोग करने के लिए सबसे अच्छा बनाता है। यह विधि के लिए "स्थानीय चर तालिका" में दिखाई दे रहा है गौर करें कि यदि आपके पास कई छोर हैं, तो अनावश्यक रूप से बड़ी गुंजाइश में घोषित चर के साथ:

 void x(String[] strings, Integer[] integers) { String s; for (int i = 0; i < strings.length; ++i) { s = strings[0]; ... } Integer n; for (int i = 0; i < integers.length; ++i) { n = integers[i]; ... } } 

वेरिएबल्स और n उनके संबंधित छोरों में घोषित किए जा सकते हैं, लेकिन जब से वे नहीं हैं, तो कंपाइलर स्टैक फ्रेम में दो "स्लॉट" का उपयोग करता है यदि वे लूप के भीतर घोषित किए गए थे, तो संकलक एक ही स्लॉट का पुन: उपयोग कर सकता है, जिससे स्टैक फ़्रेम छोटे हो सकते हैं।

वास्तव में क्या मायने रखती है

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

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

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

इसलिए, यदि आपका कंपाइलर किसी भी अनुकूलन के बराबर है, तो कोई अंतर नहीं है

सामान्य तौर पर मैं दूसरा विकल्प चुनता हूं, क्योंकि 'वैरिएबल' का दायरा लूप तक सीमित है I लाभ:

  • यह प्रोग्रामर के लिए बेहतर है क्योंकि आपको फ़ंक्शन में कहीं और बाद में उपयोग किए जाने के बारे में चिंता करने की आवश्यकता नहीं है
  • यह संकलक के लिए बेहतर है क्योंकि चर का दायरा छोटा है, और इसलिए यह संभवतः अधिक विश्लेषण और अनुकूलन कर सकता है
  • यह भविष्य के पाठकों के लिए बेहतर है क्योंकि उन्हें आश्चर्य नहीं होगा कि क्यों वे 'वैरिएबल' को लूप के बाहर घोषित कर दिए गए हैं यदि यह कभी बाद में इस्तेमाल नहीं किया जाता है

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

के बजाय

 for (int i = 0; i < array.length; i++) { Object next = array[i]; } 

मैं पसंद करता हूं

 for (int i = 0, max = array.lenth; i < max; i++) { Object next = array[i]; } 

किसी भी अन्य चीजें जिन्हें माना जाना चाहिए, पहले से ही उल्लेख किया गया है, इसलिए सिर्फ मेरे दो सेंट (एरिकॉन्स पोस्ट देखें)

ग्रीटिंगज़, जीहाड

@ एस्टेबन अरया के उत्तर के लिए थोड़ा सा जोड़ने के लिए, दोनों को लूप के माध्यम से प्रत्येक बार प्रत्येक स्ट्रिंग के निर्माण की आवश्यकता होगी ( some Assignment अभिव्यक्ति के रिटर्न मूल्य के रूप में) उन तारों को किसी भी तरह से एकत्र कचरा होने की आवश्यकता है।

मुझे पता है यह एक पुराना सवाल है, लेकिन मैंने सोचा कि मैं थोड़ा जोड़ूंगा जो थोड़ा संबंधित है।

जावा स्रोत कोड ब्राउज़ करते समय मैंने देखा है कि कुछ विधियां, जैसे String.contentEquals (नीचे दोहराया गया) अनावश्यक स्थानीय चर बनाता है जो केवल क्लास चर की प्रतियां हैं मेरा मानना ​​है कि कहीं एक टिप्पणी थी, जो कि स्थानीय चर तक पहुंचने से वर्ग चर तक पहुंचने से तेज़ है।

इस मामले में "वी 1" और "वी 2" अपेक्षाकृत अनावश्यक हैं और कोड को सरल बनाने के लिए समाप्त किया जा सकता है, लेकिन प्रदर्शन को बेहतर बनाने के लिए जोड़ा गया है।

 public boolean contentEquals(StringBuffer sb) { synchronized(sb) { if (count != sb.length()) return false; char v1[] = value; char v2[] = sb.getValue(); int i = offset; int j = 0; int n = count; while (n-- != 0) { if (v1[i++] != v2[j++]) return false; } } return true; } 

मुझे लगता है कि हमें समस्या की अधिक विशिष्टता की आवश्यकता है

 s = some Assignment; 

यह निर्दिष्ट नहीं है कि यह किस प्रकार का असाइनमेंट है यदि असाइनमेंट है

 s = "" + i + ""; 

तो एक नया स्टिंग आवंटित किए जाने की आवश्यकता है।

लेकिन अगर यह है

 s = some Constant; 

s केवल स्थैतिक स्मृति स्थान को इंगित करता है, और इस प्रकार पहला संस्करण अधिक स्मृति कुशल होगा

मुझे कुछ मूर्खतापूर्ण लगता है कि किसी लंग आईएमएचओ के लिए लूप के बहुत अनुकूलन के बारे में चिंता हो।

जब मैं कई धागे (50+) का उपयोग कर रहा हूं तो मुझे भूत थ्रेड मुद्दों को संभालने का एक बहुत ही प्रभावी तरीका मिल गया है ताकि कोई प्रक्रिया सही ढंग से बंद न कर सकी। अगर मैं गलत हूँ, तो कृपया मुझे बताएं क्यों मैं गलत हूँ:

 Process one; BufferedInputStream two; try{ one = Runtime.getRuntime().exec(command); two = new BufferedInputStream(one.getInputStream()); } }catch(e){ e.printstacktrace } finally{ //null to ensure they are erased one = null; two = null; //nudge the gc System.gc(); }