2012-02-26 15 views
13

तो मुझे लगता है कि मैं खुद को निम्नलिखित पैटर्न की तरह कुछ कर रहा हूं। बजाय:जावा पैटर्न: अस्थायी चर का उपयोग करने के लिए यह समझ में आता है

if (map.containsKey(someKey)) { 
    Value someValue = map.get(someKey); 
    ... 
} 

(और के बाद से मैं जानता हूँ कि मेरी नक्शा nulls की दुकान नहीं है), मैं करूँगा नक्शा पार नहीं करने के लिए दो बार:

Value someValue = map.get(someKey); 
if (someValue != null) { 
    ... 
} 

यह लगता है के लिए मुझे एक सार्थक होने के लिए पैटर्न दिया गया है कि Map संचालन संचालन और अनुकूलक की एक सभ्य संख्या निष्पादित करता है, मुझे लगता है कि इसे अनुकूलित करने के लिए पर्याप्त स्मार्ट नहीं है।

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

if (someObject.someMethod() != null) { 
    processSomehow(someObject.someMethod()); 
} 

मैं एक "रचनात्मक नहीं" सवाल यह सीमाओं बताएं ताकि मैं जवाब है कि कुछ तथ्य और सिर्फ अनुमान के बजाय संदर्भ पेश की तलाश में हूँ।

  • जब यह यह करने के लिए कोई मतलब है और जब यह नहीं है?
  • एक अस्थायी चर का उपयोग कब किया जाना चाहिए यह निर्धारित करने के लिए someMethod() की "लागत" का मूल्यांकन कैसे करना चाहिए?
  • सरल विधियों जैसे विधियों के लिए, क्या यह हॉटस्पॉट कंपाइलर या ऑप्टिमाइज़र के रास्ते में हो सकता है और वास्तव में कम कुशल कोड उत्पन्न करता है?

वंशावली के लिए, मैं नहीं पूछ रहा हूं "मैं अपने मौजूदा कार्यक्रम की गति को कैसे सुधार सकता हूं"। मैं यह जानने की कोशिश कर रहा हूं कि "भविष्य में कोड लिखते समय मुझे किस पैटर्न का उपयोग करना चाहिए"।

किसी भी जानकारी के लिए धन्यवाद।

+6

मुझे लगता है कि इन सभी सवालों के जवाब में "प्रोफाइलर" शब्द शामिल है ... –

+4

स्पष्ट रूप से यदि 'someMethod() 'महंगा है या इसके दुष्प्रभाव हैं तो आप इसे दो बार कॉल नहीं करना चाहते हैं। जावा (अभी तक) में 'idempotent' कीवर्ड नहीं है (पीएल/1 :-) –

+0

अच्छा बिंदु @ जिम में' कमी 'की पुरानी यादें लाता है। मैंने अपने प्रश्न को और अधिक स्पष्ट करने के लिए संपादित किया है कि मैं साइड इफेक्ट्स के बारे में बात नहीं कर रहा हूं। लेकिन मैं इस बारे में बात कर रहा हूं कि विधि के "व्यय" का मूल्यांकन कैसे किया जाए। – Gray

उत्तर

11

किसी अस्थायी चर का उपयोग कब किया जाना चाहिए यह निर्धारित करने के लिए मुझे कुछ विधि() की "लागत" का मूल्यांकन कैसे करना चाहिए?

बस someMethod() के कार्यान्वयन को देखें। यदि यह सिर्फ एक फ़ील्ड देता है - जैसे कि आमतौर पर गेटर विधि की तरह, स्थानीय चर (प्रदर्शन के अनुसार) घोषित करने की आवश्यकता नहीं होती है। यदि विधि ऑब्जेक्ट बनाता है, डेटाबेस को कॉल करता है या फ़ाइल सामग्री को पढ़ता है, तो आमतौर पर वापसी मान को कैश करने के लिए बुद्धिमान होता है।

व्यक्तिगत रूप से, मुझे अस्थायी चर घोषित करने के कारण प्रदर्शन समस्याओं की परवाह नहीं है। मैं दो बार एक विधि को कॉल करने के बजाय वापसी मूल्य रखता हूं। कोड बहुत आसान को पढ़ने के लिए और समझने के लिए है (जब तक आप उन सभी चर नाम सिर्फ temp ;-))

+0

युगल अच्छा विनिर्देश (डेटाबेस, नई वस्तु) वहाँ @Andreas लेकिन क्या आप किसी विधि की लागत का मूल्यांकन करने के बारे में कुछ और विवरण प्रदान कर सकते हैं। यह उस पर "देखो" के रूप में सरल नहीं है। – Gray

+2

मेरा दहलीज बहुत कम है। सब कुछ महंगा है तो 'वापसी mValue;' कैश किया जाएगा;) - बीटीडब्ल्यू, मुझे विश्वास है, हम कोड को देखकर जटिलता/लागत का अनुमान लगा सकते हैं। –

+0

मैं और जानकारी प्राप्त करने की कोशिश कर रहा था। "सबकुछ महंगा है तो एमवीएलयू लौटाएं;" जिसकी मुझे तलाश थी वह है। धन्यवाद। – Gray

5

जाहिर है मैं someMethod (फोन नहीं कर सकते हैं) दो बार अगर कोई दुष्प्रभाव हैं लेकिन जब यह पड़ता है ऑप्टिमाइज़ेशन दृष्टिकोण से इसे केवल एक बार कॉल करने का अर्थ है?

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

+2

मुझे लगता है कि "उदारतापूर्वक" योग्यता प्राप्त करने की आवश्यकता हो सकती है। एक-प्रयोग चर के साथ अपने तरीकों को झुकाव में इसके डाउनसाइड्स भी हैं। –

+1

दरअसल, जब भी मुझे चर के बिना दो बार ऑपरेशन करने की आवश्यकता होती है, तो मैं एक परिचय देता हूं। –

+0

मेरे पास मेरे आवेदन को प्रोफ़ाइल करने का समय नहीं है जब भी मुझे मूल्यांकन करना होगा कि मुझे अस्थायी चर की आवश्यकता है या नहीं। क्या आप कोडिंग करते समय @larsmans के लिए कोई पैटर्न देख रहे हैं? – Gray

5

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

खासकर जब someMethod() एक तुल्यकालन विधि की तरह महंगा है तो यह काफी बेहतर प्रदर्शन करना चाहिए। लेकिन जब someMethod() एक सिंक्रनाइज़ विधि है तो इसे समरूपता में एकाधिक धागे द्वारा बुलाया जाना है और फिर यह विधि को दो बार कॉल करने या उसके रिटर्न वैल्यू को स्टोर करने और इसे पुन: उपयोग करने में अंतर बनाता है ...

... एक और बिंदु उल्लेख करने के लिए कि बाद की विधि कॉल को एक ही डेटा वापस करने की आवश्यकता नहीं है। तो स्थानीय संस्करण के साथ/बिना आपके उदाहरण बाद के विधि कॉल के लिए हमेशा वैध विकल्प नहीं होते हैं। लेकिन मुझे लगता है कि आप इसे पहले से ही मानते हैं।

+0

मैंने इस पर कभी टिप्पणी नहीं की लेकिन आपके उत्तर के लिए धन्यवाद। मैंने इसे +1 दिया। अच्छे अंक। – Gray

1

समान नेट Dictionary उपयोग शैली के बारे में एक चर्चा का मुझे याद दिलाता है: What is more efficient: Dictionary TryGetValue or ContainsKey+Item?

सामान्य तौर पर, के रूप में टिप्पणी में कहा, आप अपने कार्यक्रम में प्रदर्शन हॉट स्पॉट पता नहीं है जब तक आप इसे वास्तविक डेटा के साथ चलाने एक प्रोफाइलर के तहत।

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

2

मेरे लिए यह सब कार्यक्रम के तर्क को और प्रदर्शन के लिए नहीं निर्भर करता है। तो

if (map.containsKey(someKey)) { 
    Value someValue = map.get(someKey); 
    ... 
} 

कि कोड के बराबर नहीं सभी मामलों में है:

Value someValue = map.get(someKey); 
if (someValue != null) { 
    ... 
} 

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

इसके अलावा किसी भी तरह के साथ इस कोड तार्किक मुद्दे हैं। इस पर विचार करें:

BufferedRead reader = ...; 
if (reader.readLine() != null) { 
    processSomehow(reader.readLine()); 
} 

यहाँ यह स्पष्ट है कि readLine दो बार बुलाया जाना चाहिए। इस तरह के कोड के लिए एक और समस्या डोमेन बहुप्रणाली है: कोड अपेक्षा करता है कि मान बदलना न पड़े, लेकिन दूसरा धागा उत्साहपूर्वक ऐसा कर सकता है।

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

+0

मैं तर्क @ एएच के बारे में बात नहीं कर रहा था .. मैं समझता हूं कि जब मैंने अस्थायी चर का उपयोग करने के लिए _need_ किया था। जब यह सिफारिश की गई थी तो मैं यह पता लगाने की कोशिश कर रहा था। – Gray

+0

@ ग्रे: मैं आपकी बात समझ गया। मेरा मुद्दा है: तर्क पहले आता है।जब तर्क निर्देशित करता है, वही मान अपेक्षित है, तो चर का उपयोग किया जाना चाहिए। इसलिए आपके दोनों उदाहरण तार्किक रूप से गलत या संदिग्ध हैं। तो: चर का उपयोग करके _not_ असली अपवाद है। –

+0

मेरा कोड न तो तार्किक रूप से गलत है और न ही संदिग्ध दोस्त है। मुझे पता है कि मेरा 'मानचित्र' या तो नल स्वीकार नहीं करता है या मैं उन्हें वहां कभी स्टोर नहीं करता हूं। ऐसा लगता है कि किसी और को स्पष्टीकरण की आवश्यकता नहीं है। आप पूरी तरह से मेरे प्रश्न के बिंदु चूक गए जवाब। – Gray

2

कई लोग Knuth (या तो स्पष्ट रूप से या स्पष्ट रूप से) उद्धृत कर रहे हैं, लेकिन मुझे लगता है कि यह हमेशा एक डिजाइन पैटर्न के रूप में समझ में आता है (और ऐसे मामलों जहां null एक स्वीकार्य कुंजी है, as pointed out by A.H. यह और अधिक स्पष्ट हो जाता है)। मेरे दिमाग में, यह मूल्य के बजाय C++ में कॉन्स्ट संदर्भ द्वारा एक चर पारित करने के मामले के समान है।ऐसा करने के दो कारण हैं: (ए) यह संचार करता है कि मूल्य नहीं बदलेगा, लेकिन मुख्य कारण यह है कि यह मामूली तेजी से है। इससे अधिकतर व्यक्तिगत कॉल पर कोई फर्क नहीं पड़ता, लेकिन जब प्रत्येक दिनचर्या प्रत्येक पैरामीटर को मूल्य से गुजरती है, तो आप इसे देखते हैं। यह एक अच्छी आदत है। यदि आप उल्लेख करते हैं तो यह सामान्य नहीं है और इसलिए यह उतना महत्वपूर्ण नहीं है, लेकिन मैं तर्क दूंगा कि यह अभी भी एक अच्छी आदत है।

+0

धन्यवाद। अच्छे अंक। – Gray

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

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