2012-03-20 11 views
9

का अक्षम उपयोग मैं अपने जावा-एप (नेटबीन के साथ आईडीई के साथ) में लॉगर बना रहा था, अचानक अचानक मैंने एक चेतावनी देखी: "लॉगर में स्ट्रिंग कॉन्सटेनेशन का अक्षम उपयोग"।स्ट्रिंग कॉन्सटेनेशन

मेरे oringinal कोड

srcLogger.getLogger().log(Level.INFO,"UploadBean.doUpload completado [" + file.getName() + "]\n"); 

है, लेकिन NetBeans एक टेम्पलेट को परिवर्तित करने का सुझाव दिया इस कोड को दे रही है (जो एक "टेम्पलेट" यहाँ का मतलब है?): क्या इन दोनों के बीच अलग है

srcLogger.getLogger().log(Level.INFO, "UploadBean.doUpload completado [{0}]\n", file.getName()); 

संगतता के दो तरीके, मैंने कभी बाद वाले का उपयोग नहीं किया।

चीयर्स।

उत्तर

11

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

सुझाया गया प्रतिस्थापन स्ट्रिंग्स को संयोजित नहीं करता है लेकिन इसे टेम्पलेट को पार्स करने और पैरामीटर के साथ मर्ज करने के लिए कुछ अतिरिक्त प्रोसेसिंग की आवश्यकता होती है।

नेटबीन्स, यह एक बुरी सलाह है।

यह जावा 1.5+ के लिए सच है। जावा के पुराने संस्करण संयोजन दौरान अप्रयुक्त String उदाहरणों का एक बहुत बनाने के (हो सकता है) ..

+3

चेतावनी को बंद करने के लिए (नेटबीन 7.2.1 में): प्राथमिकताएं -> संपादक -> संकेत -> लॉगिंग -> लॉगर में स्ट्रिंग कॉन्सटेनेशन। विवरण कहता है, " यह लॉगर संदेशों में तारों को संयोजित करने के लिए प्रदर्शन करने योग्य नहीं है। प्लेसहोल्डर के साथ एक टेम्पलेट संदेश का उपयोग करना बेहतर है, जिसे कंक्रीट मानों द्वारा प्रतिस्थापित किया जाता है जब संदेश वास्तव में लॉग इन होने जा रहा है।" –

+0

असल में आप प्रमुख फायदों में से एक को याद करते हैं, मैं देर से होने के बावजूद एक उत्तर जोड़ूंगा :) –

+3

लेकिन चेतावनी हमेशा निष्पादित करने के विरोध में एक अक्षमता है क्योंकि इसे केवल वर्तमान लॉगिंग स्तर के आधार पर निष्पादित करने के विरोध में ['लॉग (स्तर स्तर, स्ट्रिंग संदेश, ऑब्जेक्ट [] पैरा) का उपयोग करने के लिए '] (https://docs.oracle।com/javase/8/docs/api/java/use/logging/logger.html # log-java.util.logging.Level-java.lang.String-java.lang.Object: A-) विधि। – Adam

4

चूंकि तार जावा में अपरिवर्तनीय हैं, जब आप String ऑब्जेक्ट्स को संयोजित करते हैं तो आप वास्तव में एक पूरी तरह से नई वस्तु बनाते हैं। टेम्पलेट जैसे कुछ का उपयोग नेटबीन्स सुझाव देता है या StringBuilder आपको उन सभी मध्यवर्ती वस्तुओं को बनाने से रोकता है, जो समय और संसाधन लेते हैं।

+0

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

11

यहाँ असली जीत है आप अगर किसी भी स्ट्रिंग सब (या तो संयोजन या टेम्पलेट विस्तार) पर से निपटने करने के लिए की जरूरत नहीं है कि लॉगजर को INFO स्तर पर लॉग इन करने के लिए कॉन्फ़िगर किया गया है।

यही है कि लॉगर किसी भी तरह के स्ट्रिंग मैनिपुलेशन के पास कहीं भी जाने के बिना कुछ भी करने का फैसला नहीं कर सकता है।

1

एक टेम्पलेट का अर्थ है कि, यह एक स्ट्रिंग के बजाए स्ट्रिंग के लिए एक टेम्पलेट माना जाता है। विचार यह है कि {0} बिट को पहले तर्क के साथ प्रतिस्थापित किया जाएगा जो सूची में इसके बाद दिखाई देता है (file.getName())। यह String की format विधि के पैटर्न का पालन करता है।

मैंने यह देखने के लिए कोई प्रदर्शन परीक्षण नहीं देखा है कि यह तेज है या नहीं। जैसा कि अन्य उत्तरों ने इसे छोड़ने की ओर इशारा किया है, यह विशेष रूप से धीमा नहीं होगा क्योंकि StringBuilder को संकलक द्वारा नियमित स्ट्रिंग के स्थान पर उपयोग किया जाएगा। हालांकि, जैसा कि @dty बताता है, मुझे लगता है कि यह लॉग इन स्तर पर सेट होना चाहिए ताकि लॉगिंग स्तर सेट हो सके ताकि कथन वास्तव में लॉग न हो, क्योंकि आउटपुट में स्ट्रिंग बनाने के लिए कोई काम आवश्यक नहीं है। साथ ही, चूंकि संपूर्ण टेम्पलेट स्ट्रिंग एक शाब्दिक है, इसलिए इसे कंपाइलर द्वारा स्ट्रिंग पूल में जोड़ा जाएगा। इसका मतलब यह है कि इस विशेष String के सभी उदाहरण एक ही वास्तविक उदाहरण को इंगित करेंगे - इसलिए यदि कथन वास्तव में लॉग नहीं किया गया है तो इसे इस स्ट्रिंग को स्टोर करने के लिए स्मृति आवंटित करने की भी आवश्यकता नहीं है, यह केवल इसे दिखता है, जो होना चाहिए अधिक कुशल।

1

नेटबीन से आपको जो चेतावनी मिलती है वह आपको लॉग स्टेटमेंट में कॉन्सटेनेशन से बचने के लिए सबसे छोटा औचित्य दे रही है।

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

लेकिन लॉग संदेश के लिए टेम्पलेट शैली का उपयोग करने का चयन करने के कुछ अन्य कारण हैं।

ए। Concat के संभावित ओवरहेड से बचें। जैसा कि अन्य ने बताया है, हालिया जावैक के साथ यह एक बड़ा मुद्दा नहीं है।

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

16

संदेश स्ट्रिंग कॉन्सटेनेशन की लागत का जिक्र नहीं कर रहा है। अन्य उत्तरों बिल्कुल सही होते हैं जब वे कहते हैं कि एक स्ट्रिंगबिल्डर का उपयोग किया जाएगा।

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

हमें इन दो उदाहरणों का प्रयोग करते हैं:

srcLogger.getLogger().log(Level.INFO,"UploadBean.doUpload completado [" + file.getName() + "]\n"); 
srcLogger.getLogger().log(Level.INFO, "UploadBean.doUpload completado [{0}]\n", file.getName()); 

पर डिबग स्तर की जानकारी के साथ

डीबग स्तर INFO बंद के साथ: दूसरा उत्तर फ़ाइल ऑब्जेक्ट (जो एक साधारण क्वेरी है) के नाम से गुज़रता है, लॉग() विधि INFO स्तर की जांच करती है और तुरंत लौटती है। नहीं String प्रसंस्करण बिल्कुल किया जाता है!

अब कल्पना करें कि एक साधारण file.getName() के बजाय हम एक और जटिल वस्तु लॉगिंग कर रहे थे, जिसकी खुद को toString() विधि में बहुत सी स्ट्रिंग कॉन्सटेनेशन की आवश्यकता थी। उन वस्तुओं को लॉग इन करके सीधे उस प्रक्रिया में से कोई भी नहीं किया जाता है। toString() कभी भी तब तक नहीं बुलाया जाता है जब तक डीबग स्तर प्रदर्शित नहीं किया जाता है।

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

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