2012-02-28 20 views
6

अक्सर, मैं कोड जहां मनुष्य विधि बार-बार दुरुपयोग किया प्रयोग किया जाता है/पूर्व के लिए, कुछ मूल्य मिलता है या एक विधि पैरामीटर के रूप में इसे पारित करने के पार चलो यह, जैसा कि नीचे:Accessor विधि प्रदर्शन और अनुकूलन

public class Test { 
    public void someMethod() { 
     String name = person.getName(); 
     if(name != null && name.equalsIgnoreCase("Einstein")) { 
      method1(name); 
     } 
     method2(name); 
     method3(name); 
     method4(name); 
    } 

मेरी राय में, वहाँ, एक चर के लिए गेटर बताए और इसे का उपयोग करने में काफी स्मृति/प्रदर्शन लाभ के रूप में Getters जावा तरीकों और उपयोग ढेर फ्रेम हैं। क्या इस तरह कोडिंग में वास्तव में एक बड़ा फायदा है? }

+0

क्यों नहीं यह कोशिश करते हैं और देखते हैं? प्रदर्शन लाभ को मापना आसान होगा हालांकि अभी भी सटीक परिणाम प्राप्त करने की देखभाल की आवश्यकता है ... – DNA

+3

इस बात पर निर्भर करता है कि कम्प्यूटेशनल रूप से महंगा 'getName' कितना महंगा है। यदि 'getName' ताले और सिंक्रनाइज़ेशन से भरा एक हजार लाइन विधि चाक है, तो हाँ, आपको कुछ समस्याएं हो सकती हैं। फिर फिर, आप नहीं कर सकते हैं। इसके अलावा यदि एकाधिक कॉल अलग-अलग मान वापस कर सकते हैं, तो दोनों दृष्टिकोण अर्थात् अलग-अलग हो सकते हैं। –

+4

आप उसी वाक्य में "गेटटर" और "सर्वश्रेष्ठ अभ्यास" का उपयोग नहीं कर सकते हैं, जब तक कि प्रेषण "गेटटर विधियों का उपयोग सर्वोत्तम अभ्यास के विपरीत नहीं है"। – DwB

उत्तर

16

आप हाल ही में प्रोफाइल अपने राय है।

प्रदर्शन:

यह एक सूक्ष्म अनुकूलन था कि एक पूर्व 1.2 JVM में 1999-2001 में ध्यान देना करने के लिए कुछ और फिर भी मैं यह सवाल उठाया है होगा जब तक कि कुछ गंभीर संख्या से पता चला गया हो सकता है अन्यथा।

आधुनिक जेआईटी कार्यान्वयन आपको बताएंगे कि आज आपके राय जगह से बाहर है।

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

तर्क:

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

विशेष रूप से यदि वापसी हुई तो String के विपरीत कुछ परिवर्तनीय था जो अपरिवर्तनीय है। फिर भी स्थानीय प्रतिलिपि बदल सकती है, जब तक कि आपने गहरा क्लोन नहीं किया हो, और वास्तव में गलत होने में वास्तव में आसान हो जाता है।

चिंता खुद यह कर सही ढंग से, तो उपाय और उसके बाद का अनुकूलन क्या जब तक यह कोड कम पोषणीय नहीं है महत्वपूर्ण है के साथ।

JVM final उदाहरण के सदस्यों को किसी भी कॉल इनलाइन और विधि कॉल को दूर करता है, तो वहाँ विधि return this.name; यह जानता है के अलावा अन्य कॉल में कोई बात नहीं एक्सेसर विधि में तर्क नहीं है कि है और यह जानता है संदर्भ final इतना है जाएगा यह जानता है कि यह मूल्य को रेखांकित कर सकता है क्योंकि यह नहीं बदलेगा।

कि अंत

person.getName() != null && person.getName().equalsIgnoreCase("Einstein") 

करने के लिए अधिक सही ढंग से

person != null && "Einstein".equalsIgnoreCase(person.getName()) 

के रूप में व्यक्त किया जाता है एक NullPointerException

पुनर्रचना होने की कोई संभावना नहीं है, क्योंकि:

आधुनिक आईडीई रिफैक्टरिंग टी ओल्स भी स्थानों के समूह में कोड बदलने के बारे में किसी भी तर्क को हटा दें।

2

यदि जावा में कुछ करने का आपका तर्क है क्योंकि "यह बेहतर प्रदर्शन कर सकता है", तो आप इसे गलत कर रहे हैं। जेआईटी कंपाइलर मामूली मामला public String getName(){return name;} दूर अनुकूलित करेगा। इसके बजाए, आपको यह निर्णय लेने के आधार पर निर्णय लेना चाहिए, "क्या यह सही ओओपी तरीका है"

ओओपी दृष्टिकोण से, केवल गेटर का उपयोग करें। फिर, एक उप-वर्ग अन्य फैंसी चीजों को करने के लिए आवश्यक विधि को ओवरराइड कर सकता है (जैसे "आइंस्टीन" नाम को अनदेखा करें)।

+1

पोस्टर एक गेटर का उपयोग करने में विफल नहीं था। गेटटर को बार-बार कॉल करने के बजाए कोड के उसी ब्लॉक में केवल एक बार बुलाया जा रहा है। विधि ओवरराइडिंग की उदाहरण की शुद्धता पर कोई प्रभाव नहीं पड़ेगा। –

+1

यह होगा कि रिटर्न स्टेटस बदल गया है कि कितनी बार getXXX एक्सेसर को कॉल किया गया था :-) –

+0

तो यह एक वास्तविक गेटर नहीं होगा यदि इसका दुष्प्रभाव –

4

कोई प्रदर्शन अंतर नहीं है। यदि वहां है, तो यह मामूली छोटा है।

अधिक महत्वपूर्ण बात यह है कि दो कोड नमूने वास्तव में एकाधिक धागे की उपस्थिति में पूरी तरह अलग व्यवहार करते हैं।

कहें कि आधे रास्ते से, कोई setName पर कॉल करता है और नाम बदलता है। अब आपका कोड पूरी तरह अप्रत्याशित पथ से गुजर रहा है! यह वास्तव में कुछ ऐतिहासिक (यहां तक ​​कि कर्नेल-स्तर) सुरक्षा भेद्यता का मूल कारण रहा है।

ध्यान दें कि मैं स्थानीय चर में आने वाले सभी परिणामों की अंधाधुंध प्रतिलिपि बनाने की वकालत नहीं कर रहा हूं। मैं सिर्फ एक संभावित गड़बड़ी को इंगित कर रहा हूं।

1

यदि आप स्थानीय चर में मान डालते हैं तो यह निश्चित रूप से बहुत अधिक पठनीय है, यही कारण है कि आपको ऐसा करना चाहिए और ऐसा नहीं क्योंकि यह बेहतर प्रदर्शन करता है।

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

दोनों मामलों में जो आप शायद चाहते हैं केवल getName() को केवल आह्वान करना है।

0

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

if(person.expensiveOp() != null && person.expensiveOp().equalsIgnoreCase("Einstein")) { 
     method1(person.expensiveOp()); 
    } 
    method2(person.expensiveOp()); 
    method3(person.expensiveOp()); 
    method4(person.expensiveOp()); 

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

0

मैंने सवाल पूछने के बाद इस विषय पर कुछ शोध किया और पाया कि मैं क्या देख रहा था। समस्या यह थी कि सवाल तैयार करते समय मैंने सही शब्दावली का उपयोग नहीं किया था। 'Inline Expansion' (कंपाइलर इनलाइनिंग) वह है जिसे मैं ढूंढ रहा था। यहाँ विकी से एक उद्धरण है:

कंप्यूटिंग में, इनलाइन विस्तार, या इनलाइन करने, एक मैनुअल या संकलक अनुकूलन कि कॉल प्राप्त करने वाला के शरीर के साथ एक समारोह कॉल साइट की जगह है। यह ऑप्टिमाइज़ेशन प्रोग्राम के अंतिम आकार को बढ़ाने की संभावित लागत ( बाइनरी फ़ाइल आकार) की संभावित लागत पर रनटाइम, पर समय और स्थान उपयोग को बेहतर बना सकता है।

मैंने यह भी पाया है कि इस विषय को पहले से ही इस साइट पर चर्चा की गई:

1) Do getters and setters impact performance in C++/D/Java?

यहाँ ऊपर के लिंक से एक उद्धरण है:

जावा में, JIT कंपाइलर शायद इसे जल्दी या बाद में रेखांकित करेगा। जितना मुझे पता है, जेवीएम जेआईटी कंपाइलर केवल भारी इस्तेमाल किए गए कोड को अनुकूलित करता है, ताकि आप गेटटर/सेटर को पर्याप्त रूप से कहलाते समय तक फ़ंक्शन कॉल ओवरहेड प्रारंभ में देख सकें।

2) Inlining In Java

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