2013-02-04 23 views
6

क्या पाशपाश प्रदर्शन के लिए जावा

के लिए

इस में बेहतर है:

for(int i = 0; i<someMethod(); i++) 
{//some code 
} 

या:

int a = someMethod(); 
for(int i = 0; i<a; i++) 
{//some code 
} 

चलो बस का कहना है कि someMethod() रिटर्न कुछ बड़े।

सबसे पहले विधि someMethod() प्रत्येक पाश इस प्रकार की गति को कम करने में, निष्पादित दूसरा तेजी से होता है, लेकिन मान लीजिए कि आवेदन में इसी तरह के छोरों का एक बहुत इतना घोषित एक चर Vill अधिक स्मृति का उपभोग देखते हैं कि करने देगा।

तो बेहतर क्या है, या मैं बस बेवकूफ सोच रहा हूं।

+0

में है आपका उदाहरण 'ए' स्थानीय चर है, इसलिए यह केवल स्मृति को खपत करता है जबकि निष्पादन ब्लॉक के अंदर होता है जहां इसे परिभाषित किया जाता है। –

उत्तर

11

दूसरा बेहतर है - मानते हैं कि someMethod() में side effects नहीं है।
यह वास्तव में someMethod() द्वारा गणना की गई मान को कैश करता है - इसलिए आपको इसे फिर से समझना नहीं होगा (माना जाता है कि यह अपेक्षाकृत विस्तृत ओप है)।

यदि ऐसा है (साइड इफेक्ट) - दो कोड स्नैप बराबर नहीं हैं - और आप सही है क्या करना चाहिए।

"चर एक के लिए आकार" के बारे में - यह कोई मुद्दा वैसे भी, someMethod() जरूरतों का लौटे मूल्य वैसे भी गणना से पहले कुछ मध्यवर्ती अस्थायी चर पर संग्रहीत किया जा करने के लिए नहीं है (और यहां तक ​​कि अगर यह मामला नहीं था, एक पूर्णांक का आकार नगण्य है)।

पीएस
कुछ मामलों में, कंपाइलर/जेआईटी ऑप्टिमाइज़र दूसरे कोड को दूसरे में अनुकूलित कर सकता है, निश्चित रूप से कोई दुष्प्रभाव नहीं मानता है।

+0

धन्यवाद, 'साइड इफेक्ट्स' – pedja

+1

+1 इतना कठिन है कि मैं हमेशा इसके खिलाफ सलाह देता हूं। जब तक आप जेनरेट किए गए असेंबलर को जांचने के लिए तैयार न हों और जानें कि JVM ऑप्टिमाइज़ करता है कि यह एक कठिन कार्य है – exexzian

4

यदि संदेह में, परीक्षण। एक प्रोफाइलर का प्रयोग करें। का आकलन करें।

+0

लिखने के लिए माइक्रोबेंमार्क लिखने के लिए बहुत अच्छा स्पष्टीकरण – bestsss

4

यात्रा आदेश मान लिया जाये कि प्रासंगिक नहीं है, और यह भी यह सोचते हैं क्या तुम सच में करना चाहते हैं अपने कोड नैनो का अनुकूलन, आप यह कर सकते हैं:

for (int i=someMethod(); i-->0;) { 
    //some code 
} 

लेकिन एक अतिरिक्त स्थानीय चर (अपने a) नहीं है इतना बोझ अभ्यास में, यह आपके दूसरे संस्करण से बहुत अलग नहीं है।

+2

आप पठनीयता की कीमत पर नैनो-अनुकूलन कर रहे हैं ... इस बात का कोई सबूत नहीं है कि अधिक पठनीय (स्पष्ट) अनुकूलित संस्करण सिर्फ नहीं होगा जितना तेज़। –

+0

हम ... मुझे नहीं लगता कि कम से कम मेरे द्वारा दिखाए गए कोड में यह कम पठनीय है। मेरी राय में नकारात्मकता यह है कि पाठकों और रखरखावकर्ता आमतौर पर बढ़ रहे हैं कि मैं विशेष रूप से बढ़ रहा हूं जब आप किसी सूची में पुनरावृत्ति कर रहे हों। –

+0

@dstroy - मैं जो कह रहा हूं उसे समझने के लिए मेरा उत्तर देखें। –

2

यह वास्तव में निर्भर करता है कि कुछ विधि() के आउटपुट को उत्पन्न करने में कितना समय लगता है। इसके अलावा स्मृति उपयोग समान होगा, क्योंकि कुछ विधि() को पहले उत्पादन उत्पन्न करना होता है और फिर इसे स्टोर करना होता है। दूसरा तरीका आपके सीपीयू को प्रत्येक लूप के समान आउटपुट की गणना करने से सुरक्षित करता है और इसे और अधिक स्मृति नहीं लेनी चाहिए। तो दूसरा एक बेहतर है।

2

मैं वैरिएबल की स्मृति खपत को एक समस्या के रूप में नहीं मानूंगा क्योंकि यह एक int है और 64 बिट मशीन पर 1 9 2 बिट की आवश्यकता है। तो मैं दूसरा विकल्प पसंद करूंगा क्योंकि निष्पादन दक्षता बेहतर है।

3

आप पाश के बाद इस चर की जरूरत नहीं है, वहाँ इसके अंदर छिपाने के लिए आसान तरीका है:

for (int count = someMethod(), i = 0; i < count; i++) 
{ 
    // some code 
} 
0

आप इस अनुकूलन करने के लिए की जरूरत है, तो यह साफ/स्पष्ट यह करने के लिए तरीका है:

int a = someMethod(); 
for (int i = 0; i < a; i++) { 
    //some code 
} 

वैकल्पिक संस्करण @dystroy

for (int i=someMethod(); i-->0;) { 
    //some code 
} 

ने सुझाव दिया ... तीन समस्या है।

  • वह विपरीत दिशा में फिर से चल रहा है।

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

  • कोई सबूत नहीं है कि कोड वास्तव में अधिक बेवकूफ संस्करण की तुलना में तेज़ होगा ... खासकर जब एक बार जेआईटी कंपाइलर ने उन्हें अनुकूलित किया है। , अगर someMethod() महंगा है (के रूप में आप की मान्यता है) (और कम पठनीय संस्करण तेजी से होता है, भले ही, अंतर नगण्य होने की संभावना है।)

दूसरी ओर उसके बाद तो यह है कि कॉल "उत्थापन" यह केवल एक बार किया जा सकता है एक बार सार्थक होने की संभावना है।

+0

पहला संस्करण [लूप में आक्रमण] में कुछ विधि(), esp इनलाइन करने के लिए पर्याप्त 'इनलाइन बजट' होना चाहिए। अगर इसे ओवरराइड किया जा सकता है। कोई इनलाइनिंग का मतलब एकाधिक कॉल नहीं है और लूप को अनलोल नहीं करना + संभावित रेंज चेक। – bestsss

1

लूप अनुकूलन के बारे में सबसे महत्वपूर्ण हिस्सा JVM को लूप को अनलॉक करने की अनुमति दे रहा है। पहले संस्करण में ऐसा करने के लिए इसे someMethod() पर कॉल इनलाइन करने में सक्षम होना चाहिए। इनलाइनिंग में कुछ बजट है और यह किसी बिंदु पर फंस सकता है। अगर कुछ Method() काफी लंबा है तो JVM निर्णय ले सकता है कि यह इनलाइन करना पसंद नहीं करता है।

दूसरा संस्करण अधिक उपयोगी है (जेआईटी कंपाइलर के लिए) और बेहतर काम करने की संभावना है।

नीचे पाश डालने के लिए मेरा तरीका है: for (int i=0, max=someMethod(); i<max; i++){...}

max कोड को दूषित नहीं करता है, तो आप someMethod() की कई कॉल से कोई साइड इफेक्ट को सुनिश्चित करने और यह कॉम्पैक्ट (एकल लाइनर)

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