2015-10-05 2 views
5

मैं वर्तमान में एक PullRequest मौजूद हैं, जो की समीक्षा कर रहा हूँ:बचें अविवेक और अनावश्यक प्रणाली को बुलाती है

-  for (int i = 0; i < outgoingMassages.size(); i++) { 
+  for (int i = 0, size = outgoingMassages.size(); i < size; i++) 

https://github.com/criticalmaps/criticalmaps-android/pull/52

किसी भी तरह यह मेरे लिए गलत लगता है - सोच सकता है कि वी एम इन अनुकूलन कर रहा है - लेकिन नहीं कर सकते वास्तव में निश्चित रूप से कहो। अगर यह परिवर्तन समझ में आता है तो कुछ इनपुट प्राप्त करना अच्छा लगेगा - या पुष्टि है कि यह वीएम-साइड पर किया जाता है।

उत्तर

5

नहीं, यह वीएम अपने पाश के लिए यह संभव है कि outgoingMassages इसके आकार बदल जाएगा में

+  for (int i = 0, size = outgoingMassages.size(); i < size; i++) 

को

-  for (int i = 0; i < outgoingMassages.size(); i++) { 

से अपने कोड बदल जाएगा यकीन नहीं है। तो यह अनुकूलन JVM द्वारा लागू नहीं किया जा सकता है। अगर यह एक साझा संसाधन है तो एक और धागा outgoingMassages आकार बदल सकता है।

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

+0

क्या होगा यदि हम जानते हैं कि 'आउटगोइंग मैसेज.size() 'नहीं बदला जाएगा? क्या इसे अनुकूलित नहीं किया जाएगा, क्योंकि हमें ऑब्जेक्ट 'आउटगोइंग मैसेज' और विधि 'आकार()' हर बार कॉल करने की आवश्यकता नहीं है? – HendraWD

+0

@HendraWD यदि आप जानते हैं कि आउटगोइंग का आकार बदलता नहीं है तो लूप के दौरान आकार को एक वैरिएबल को असाइन करना एक अनुकूलन है जिसे किया जा सकता है। हालांकि, आम तौर पर, लूप के अंदर कोड में समय को कम करने के तरीके पर ध्यान देना बेहतर होता है। –

+0

ठीक है, आपकी पुष्टि के लिए धन्यवाद :) – HendraWD

1

वीएम इस अनुकूलन नहीं करेगा। चूंकि यह संभव है कि आकार() - विधि प्रत्येक कॉल के समान परिणाम नहीं लौटाता है। तो विधि प्रत्येक पुनरावृत्ति कहा जाना चाहिए।

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

बड़ा अंतर यह सुनिश्चित करने के लिए हो सकता है कि फॉर-लूप में पुनरावृत्ति की मात्रा है जो पहले से ज्ञात है। यह इस उदाहरण में मुझे समझ में नहीं आता है। लेकिन हो सकता है कि बुलाया गया तरीका बदलते हुए परिणाम लौटा सकता है जो अवांछित हैं?

0

यदि आपके संग्रह पर size() विधि सिर्फ एक निजी फ़ील्ड का मान दे रही है, तो वीएम इस में से अधिकांश को अनुकूलित करेगा (लेकिन बिल्कुल नहीं)। यह size() विधि को रेखांकित करके ऐसा करेगा, ताकि यह उस क्षेत्र तक पहुंच जाए।

शेष बिट कि अनुकूलित नहीं किया जाएगा कि नए कोड में sizefinal रूप में व्यवहार किया जाएगा करने के लिए, और इसलिए लगातार, क्षेत्र संग्रह से उठाया जबकि final (संभवतः इसे से संशोधित किया गया है के रूप में नहीं माना जाएगा है एक और धागा)। तो मूल मामले में क्षेत्र हर पुनरावृत्ति में पढ़ा जाएगा, लेकिन नए मामले में यह नहीं होगा।

0

ऐसा नहीं है कि किसी भी सभ्य अनुकूलक संभावना है - या तो वी एम पर या संकलक में - पहचान लेंगे:

class Messages { 

    int size; 

    public int size() { 
     return size; 
    } 
} 

public void test() { 
    Messages outgoingMassages = new Messages(); 
    for (int i = 0; i < outgoingMassages.size(); i++) { 

    } 
} 

और

for (int i = 0; i < outgoingMassages.size; i++) { 

को अनुकूलित अतिरिक्त कर - अपरीक्षित - अनुकूलन करना चाहिए इसलिए evil माना जाना चाहिए।

0

विधि मंगलाचरण पाश से प्रत्येक यात्रा पर हो और नहीं मुक्त लागत की है जाएगा। चूंकि आप भविष्यवाणी नहीं कर सकते कि यह कितनी बार होता है एक बार हमेशा कम होगा। यह एक मामूली अनुकूलन है लेकिन आपको अपने लिए अनुकूलन करने के लिए कंपाइलर पर भरोसा नहीं करना चाहिए।

private List<OutgoingChatMessage> outgoingMassages .. 

फिर, बुला .size() एक आभासी विधि बन जाएगा:

इसके अलावा, सदस्य outgoingMassages ..

private ArrayList<OutgoingChatMessage> outgoingMassages .. 

... एक इंटरफेस होना चाहिए। विशिष्ट ऑब्जेक्ट क्लास को जानने के लिए पदानुक्रम के सभी वर्गों के लिए विधि तालिका लागू की जाएगी। यह फिर से लागत से मुक्त नहीं है।

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