2013-04-25 8 views
9

में स्थिति की जांच करना मैं एक अनुभवी डेवलपर्स से एक सरल के बारे में पूछना चाहता हूं, लेकिन मेरे लिए स्पष्ट नहीं है। मान लें कि आप इस तरह के एक कोड (जावा) मिल गया है:लूप

for(int i=0; i<vector.size(); i++){ 
    //make some stuff here 
} 

मैं ऐसे बयानों में आए बहुत बार है, तो हो सकता है कि इसमें कुछ भी गलत नहीं है। लेकिन मेरे लिए, प्रत्येक पुनरावृत्ति में एक आकार विधि का आह्वान करना अनावश्यक लगता है। मैं इस तरह के दृष्टिकोण का प्रयोग करेंगे:

int vectorSize = vector.size(); 
for(int i=0; i<vectorSize; i++){ 
    //make some stuff here 
} 

यहाँ एक ही बात:

for(int i=0; i<myTreeNode.getChildren().size(); i++){ 
    //make some stuff here 
} 

मैं निश्चित रूप से प्रोग्रामिंग में एक विशेषज्ञ नहीं हूँ अभी तक है, तो मेरे सवाल है: मैं एक अंतराल की मांग कर रहा हूँ जहां बचाव पूरी है या पेशेवर कोड में ऐसे विवरणों का ख्याल रखना महत्वपूर्ण है?

+0

धन्यवाद - मुझे इस प्रश्न के उत्तर खोजने में कुछ समस्याएं थीं ... –

+1

कभी-कभी, आप लूप के अंदर वेक्टर के आकार को संशोधित करते हैं। आकार पहले से प्राप्त करने में कुछ भी गलत नहीं है, खासकर अगर आकार कॉल महंगा है।हालांकि, वेक्टर आकार एक महंगी कॉल नहीं है। बस समझें कि लूप शुरू करने से पहले आपको आकार क्यों मिलेगा और समझें कि आप लूप के प्रत्येक पुनरावृत्ति के बाद आकार को क्यों देखना चाहते हैं। –

उत्तर

8

एक विधि आमंत्रण की आवश्यकता है कि जेवीएम वास्तव में अतिरिक्त सामान करता है। तो आप क्या कर रहे हैं, पहले दृश्य पर एक अनुकूलन की तरह लगता है।

हालांकि, कुछ जेवीएम कार्यान्वयन इनलाइन विधि कॉल के लिए पर्याप्त स्मार्ट हैं, और उनके लिए, अंतर कोई भी नहीं होगा।

उदाहरण के लिए एंड्रॉइड प्रोग्रामिंग दिशानिर्देश हमेशा आपके द्वारा इंगित किए गए कार्यों को करने की सलाह देते हैं, लेकिन फिर, JVM कार्यान्वयन मैनुअल (यदि आप एक पर अपना हाथ प्राप्त कर सकते हैं) आपको बताएंगे कि यह आपके लिए कोड अनुकूलित करता है या नहीं।

2

आमतौर पर size() एक छोटा निरंतर समय ऑपरेशन है और इसलिए size को कॉल करने की लागत लूप बॉडी को निष्पादित करने की लागत की तुलना में तुच्छ है, और बस समय संकलक आपके लिए इस अनुकूलन का ख्याल रख सकता है; इसलिए, इस अनुकूलन के लिए बहुत अधिक लाभ नहीं हो सकता है।

यह कहा गया है कि यह अनुकूलन कोड पठनीयता को प्रतिकूल रूप से प्रभावित नहीं करता है, इसलिए यह कुछ नहीं बचा जाना चाहिए; अक्सर कोड ऑप्टिमाइज़ेशन जो केवल एक छोटे कारक द्वारा गति को प्रभावित करते हैं (उदाहरण के लिए ओ ओ (एन) ऑपरेशन को ओ (एन) ऑपरेशन में बदलने वाले ऑप्टिमाइज़ेशन के विपरीत) इस कारण से बचा जाना चाहिए, उदाहरण के लिए आप unroll a loop:

int i; 
int vectorSizeDivisibleBy4 = vectorSize - vectorSize % 4; // returns lowest multiple of four in vectorSize 
for(i = 0; i < vectorSizeDivisibleBy4; i += 4) { 
    // loop body executed on [i] 
    // second copy of loop body executed on [i+1] 
    // third copy of loop body executed on [i+2] 
    // fourth copy of loop body executed on [i+3] 
} 
for(; i < vectorSize; i++) { // in case vectorSize wasn't a factor of four 
    // loop body 
} 

लूप को अनलॉक करके चार बार आप i < vectorSize का मूल्यांकन करते हैं, जो कि आपके कोड को एक अपठनीय गड़बड़ बनाने की लागत पर चार कारकों द्वारा मूल्यांकन किया जाता है (यह भी निर्देश कैश को अपनाना पड़ सकता है, जिसके परिणामस्वरूप ऋणात्मक हो सकता है प्रदर्शन प्रभाव)। ऐसा मत करो। लेकिन, जैसा कि मैंने कहा, int vectorSize = vector.size() इस श्रेणी में नहीं आता है, इसलिए इसमें है।

+0

लेकिन निश्चित रूप से, जैसा कि लड़का संदिग्ध था, निरंतर समय संचालन एक गैर-समय के संचालन से अधिक लेता है। हालांकि अच्छा योगदान;) चीयर्स –

0

1 दृष्टि विकल्प आप सुझाव दे रहे हैं पर एक अनुकूलन तेजी, लेकिन गति के मामले में इसकी वजह से आम दृष्टिकोण को समान है,:

आकार की कॉल की जटिलता समय() फ़ंक्शन जावा वेक्टर में ओ (1) की जटिलता होती है क्योंकि प्रत्येक वेक्टर ने हमेशा अपने आकार वाले एक चर को संग्रहीत किया है, इसलिए आपको प्रत्येक पुनरावृत्ति में इसके आकार की गणना करने की आवश्यकता नहीं है, आप बस इसे एक्सेस करते हैं।

नोट: आप देख सकते हैं कि आकार() फ़ंक्शन: http://www.docjar.com/html/api/java/util/Vector.java.html बस एक संरक्षित चर तत्व को वापस कर रहा है।