2014-08-28 6 views
5

कंप्यूटिंग से बचने के लिए के लिए मैं आम तौर परजावा लिखने के लिए कैसे छोरों बार बार ऊपरी बाध्य

for (int i = 0; i < someMethod(); i++) 

को

for (int i = 0, n = someMethod(); i < n; i++) 
वरीयता में

लिखने से बचने के लिए someMethod() बार-बार की गणना की जा रही है। हालांकि मुझे ऐसा करने की ज़रूरत नहीं है जब मुझे ऐसा करने की ज़रूरत है। जावा को विधियों को पहचानने में कितना चालाक है जो हर समय एक ही परिणाम देगा और लूप की शुरुआत में केवल एक बार निष्पादित करने की आवश्यकता होगी?

+0

आप 'int n = someMethod(); 'क्यों नहीं कर सकते और उसके बाद बाद में लूप में उपयोग करें? – Adi

+1

मुझे लगता है कि http://stackoverflow.com/questions/6093537/for-loop-optimization इस प्रश्न का उत्तर देता है। – trooper

+0

एडी, यह मूल रूप से मैंने अपने पहले उदाहरण में किया है। मेरा सवाल यह है कि पहली बार गणना करने के लिए जरूरी है। मुझे यकीन है कि ऐसे कुछ उदाहरण हैं जहां मैंने लिखा है कि दूसरा तरीका पहले जैसा ही माना जाता है, लेकिन मैं इसके बारे में गलत हो सकता हूं। –

उत्तर

1

जहां तक ​​मैं कह सकता हूं, जेआईटी, केवल यह पता लगाएगा कि यह काफी सरल इनलाइन योग्य विधि है। ऐसा कहा जा रहा है कि प्रोग्रामर के लिए इन मामलों का पता लगाना बहुत आसान है और यह पता लगाने के लिए एक जेआईटी कंपाइलर के लिए एक कठिन समस्या है। अधिमानतः आपको final int का उपयोग बड़े तरीकों से परिणामों को कैश करने के लिए करना चाहिए, क्योंकि जेआईटी आसानी से पता लगा सकता है कि मान बदल नहीं सकता है और लूप को गति देने के लिए सरणी एक्सेस चेक भी हटा सकता है।

कुछ की तरह

int[] arr = new int[ 10 ]; 
for(int i = 0; i < arr.length; i++) { 
    //... 
} 

या

List<String> list = Arrays.asList(new String[] { ... }); 
for(int i = 0; i < list.size(); i++) { 
    //... 
} 

शायद बहुत आसानी से JIT द्वारा अनुकूलित किया जा सकता है। अन्य लूप जो बड़ी या जटिल विधियों को कॉल करते हैं, हमेशा एक ही मूल्य को हमेशा साबित नहीं कर सकते हैं, लेकिन आकार() जैसी विधियों को शायद इनलाइन या पूरी तरह से हटाया जा सकता है।

अंत में सरणी पर प्रत्येक लूप के साथ। वे एरे के मामले में पोस्ट किए गए पहले लूप को क्षीण कर रहे हैं, और त्वरित लूप का उत्पादन करने के लिए आसानी से अनुकूलित किया जा सकता है। हालांकि गैर-सरणी पर प्रत्येक लूप के लिए, जब मैं त्वरित लूप की बात करता हूं तो इससे बचने के लिए पसंद करते हैं, क्योंकि वे इटरेटर लूप में क्षय हो जाते हैं और न कि दूसरे लूप को पोस्ट करते हैं। यह LinkedList के लिए सच नहीं है क्योंकि ओ (एन) ट्रैवर्सल के कारण प्राप्त() का उपयोग करने से एक इटरेटर तेज है।

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

यहाँ एक link पर चर्चा पाश अनुकूलन जहां JIT हमेशा एक पाश अनुकूलित नहीं कर सकते अगर यह यह अनुकूलन कुछ भी नहीं बदलेगा है साबित नहीं कर सकते है।

+0

धन्यवाद, यह एक बहुत ही गहन जवाब है। मुझे वास्तव में यह जानने में दिलचस्पी होगी कि आकार() के अलावा कोई अन्य सामान्य तरीका है जो इस तरह से रेखांकित है। आपके दूसरे उदाहरण में, यदि पहली पंक्ति सूची सूची = Arrays.asList (arr) थी; इसके बजाय, तकनीकी रूप से आकार() लूप में बदल सकता है। क्या इस मामले में लूप और इनलाइन आकार() में एआर संशोधित नहीं किया जा रहा है जब जेआईटी पहचानने में सक्षम हो जाएगा? –

+0

@ पॉलबोडिंगटन तकनीकी रूप से arr.length किसी भी समय भी बदल सकता है। चूंकि ArrayList पर List.get() और List.size() मूल रूप से केवल एक सरणी पहुंच के आसपास रैपर होते हैं। मुझे लगता है कि एक बार जब यह रेखांकित किया गया है तो यह पहली लूप की तरह दिखता है। जो कि जेआईटी के अनुकूलन को जारी रखने के लिए पर्याप्त हो सकता है। –

+0

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

4

मेरा मानना ​​है कि प्रोग्रामर के रूप में ऑनस आपके पास है, ऐसे मामलों की पहचान करने के लिए जहां आपके for-loop की ऊपरी सीमा को फ्लाई पर गणना करने की आवश्यकता है और तदनुसार उन्हें संबोधित करने की आवश्यकता है।

यह मानते हुए कि n का मूल्य कुछ आपरेशन कि पाश के भीतर किया जाता है पर निर्भर नहीं करता, व्यक्तिगत रूप से, मैं इसे

int n = someMethod(); 
for (int i = 0; i < n; i++); 

क्योंकि यह for-loop का सबसे आम शैली को बरकरार रखता है के रूप में लिखा पसंद करेंगे, जबकि स्पष्ट रूप से परिभाषित करने ऊपरी बाउंड

+2

मैं मानता हूं कि ऑनस मुझ पर है। मैं केवल अकादमिक हित से बाहर पूछ रहा था; मैं हमेशा पहले गणना करता हूं। मैं अभी भी इसे लिखना पसंद करता हूं जैसे कि मैंने लूप के एन के दायरे को सीमित करने के लिए अपने पहले उदाहरण में किया था। –

+0

@ पॉल पूरी तरह समझ में आता है। दायरे के बारे में: यह मेरे लिए परिस्थिति है, लेकिन बढ़ी पठनीयता आमतौर पर जीत जाती है। – voidHead

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