2017-09-19 7 views
6

जेडीके 8, StringBuffer कक्षा में toStringCache है, जबकि StringBuilder नहीं है।क्यों स्ट्रिंगबिफर के पास स्ट्रिंगबिल्डर नहीं है जबकि स्ट्रिंगबिल्डर है?

/** 
* A cache of the last value returned by toString. Cleared 
* whenever the StringBuffer is modified. 
*/ 
private transient char[] toStringCache; 

लेकिन क्यों?

  • एक संभावित कारण यह है कि मैं सोच सकता हूं कि स्ट्रिंगबफर पहले ही सिंक्रनाइज़ है इसलिए कैश को कार्यान्वित किया जा सकता है।

  • या शायद ऐतिहासिक रूप से स्ट्रिंगबफर को इस तरह कार्यान्वित किया गया था इसलिए पुराना कोड इस सुविधा पर भारी निर्भर करता है?

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

+0

आपका पहला अनुमान सही है। – Flown

+0

@Flown क्या यह इसके लायक है? क्या कोई प्रदर्शन बढ़ावा होगा? अधिक कोड का मतलब है और अधिक कीड़े। – ntysdd

+1

यदि आप कई बार 'स्ट्रिंगबफर :: टूस्ट्रिंग' कहते हैं, तो एक लाभ होगा। – Flown

उत्तर

3

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

इसकी आवश्यकता क्यों होगी, यह new String(...) कन्स्ट्रक्टर का उपयोग किया जाता है;

पैकेज निजी निर्माता जो गति के लिए मान सरणी साझा करता है: कि निर्माता String(array, boolean) टिप्पणी कहते हैं इस्तेमाल किया StringBuffer के मामले में।

+1

ध्यान देने योग्य हो सकता है कि अगर आप 'StringBuffer.toString' को एक बार कॉल करते हैं, तो स्पीड लाभ भौतिक रूप से नहीं होता है, क्योंकि [कॉलर] (http://grepcode.com/file/repository.grepcode.com/java/root/ jdk/openjdk/8u40-b25/java/lang/StringBuffer.java # 669) तब एक प्रतिलिपि बनाई। परिवर्तन के बिना कई आमंत्रणों के दुर्लभ मामले में केवल एक छोटा सा लाभ हो सकता है। यह 'स्ट्रिंग' कन्स्ट्रक्टर कारखानों के लिए सही तरीके से सही ढंग से आकार देने वाले 'char []' बफर पर काम करने के लिए अधिक फायदे प्रदान करता है, इसके बाद 'स्ट्रिंग.कोनकैट (स्ट्रिंग)', 'स्ट्रिंग.रेप्लेस (चार, चार)', 'इंटीजर' .toString (int) ', आदि – Holger

4

यह ऐतिहासिक संदर्भ पर विचार करने में मदद कर सकता है। StringBuilder जावा 5 के साथ पेश किया गया था, क्योंकि यह पहचाना गया है कि StringBuffer इसके वास्तविक उपयोग मामलों के लिए उपयुक्त नहीं है।

नए पेश किए गए StringBuilder को पूरी तरह से स्थानीय संदर्भ में, निर्माण और उपयोग किए जाने के प्रमुख उपयोग के मामले के लिए डिज़ाइन किया गया है। इसलिए, यह कोई सिंक्रनाइज़ेशन प्रदान नहीं करता है और यह toString() विधि के दुर्लभ मामले को अनुकूलित करने के लिए परेशान नहीं करता है, जिसमें बदलाव के बीच कई बार कहा जाता है (वास्तविक जीवन में यह कब होता है?), खासकर वास्तव में , थ्रेड सिंक्रनाइज़ेशन के प्रदर्शन लाभ को बलि किए बिना कैशिंग सुविधा प्रदान करना, कहीं "कठिन" "असंभव" के बीच है।

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

तो यह अनुकूलन क्यों है, अगर वास्तविक जीवन में इसका कभी भी लाभ नहीं होता है? खैर, क्योंकि यह बहुत लंबे समय से है, जावा 1.0 के बाद भी सबसे अधिक संभावना है और कक्षा StringBuffer में कुछ भी बदलने के लायक नहीं है। अपनी उपस्थिति किसी भी वास्तविक लाभ नहीं हो सकता है, लेकिन न तो इसे हटाने है, जो नए परीक्षण और इतने पर की आवश्यकता होगी और बाहर बारी कुछ आवेदन के लिए space bar overheating feature होने के लिए कर सकता है ...

आपको लगता है कि वापस तो देख सकते हैं, जावा 1 में .x, बहुत से डिजाइन निर्णय किए गए थे जो आज अजीब लग सकते हैं।मौलिक कक्षाओं में synchronized का उपयोग करना उनमें से एक है, यह शायद ही कभी किसी अन्य को अनुकूलन में मदद करता है। उस समय, अपरिवर्तनीयता के प्रभाव भी अच्छी तरह से समझ में नहीं आये थे, यही कारण है कि हमारे पास String.valueOf(char[]) और String.copyValueOf(char[]), new String(char[]) का उपयोग करने का अवसर है ...

+0

मुझे नहीं पता था String.copyValueOf (char []) – ntysdd

+1

@ntysdd: ... और इन अनावश्यक 'copyValueOf' विधियों का अस्तित्व कुछ ऐसा है जिसे हमें याद रखने की आवश्यकता नहीं है। कम से कम हमारे दैनिक प्रोग्रामर के काम के लिए। – Holger

+2

@ntysdd (और @ होल्गर) निश्चित रूप से 'copyValueOf' विधियां आज अप्रासंगिक हैं। ऐतिहासिक नोट यह है कि पूर्व जेडीके 1.0, 'स्ट्रिंग (char [])' कन्स्ट्रक्टर और 'वैल्यूऑफ (char []) 'विधियों (दोनों सार्वजनिक) ने हाल ही में एक नव निर्मित स्ट्रिंग में तर्क के संदर्भ को संग्रहीत किया है। स्वाभाविक रूप से यह mutable तारों के लिए नेतृत्व किया! ऐरे की प्रतिलिपि बनाने के लिए 'copyValueOf' विधियों को जोड़ा गया था, फिर कन्स्ट्रक्टर और 'valueOf' को कॉपी बनाने के लिए भी संशोधित किया गया था, जिससे' copyValueOf' विधियों को अनावश्यक छोड़ दिया गया था। हालांकि, वे कभी साफ नहीं किया गया था। –

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