제이온

[इफेक्टिव जावा] आइटम 6. अनावश्यक ऑब्जेक्ट निर्माण से बचें

  • लेखन भाषा: कोरियाई
  • आधार देश: सभी देशcountry-flag
  • आईटी

रचना: 2024-04-28

रचना: 2024-04-28 13:40

अनावश्यक ऑब्जेक्ट बनाने के मामले

new String() का उपयोग


स्ट्रिंग a, b, c सभी "hi" स्ट्रिंग रखते हैं। हालाँकि, ये तीनों स्ट्रिंग जिन एड्रेस को रेफर करती हैं, वे सभी अलग-अलग हैं, इसलिए समान डेटा के लिए अलग-अलग मेमोरी आवंटित करने की बर्बादी होती है।


<span class="image-inline ck-widget" contenteditable="false"><img src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Fa53d14aa-6abf-40f0-8441-435647d172fa%2FUntitled.png?table=block&id=f168859c-367c-4924-a4c6-5e04788fab67&spaceId=b453bd85-cb15-44b5-bf2e-580aeda8074e&width=2000&userId=80352c12-65a4-4562-9a36-2179ed0dfffb&cache=v2" alt="Untitled" style="aspect-ratio:2000/1146;" width="2000" height="1146"></span>


इसलिए, स्ट्रिंग को घोषित करते समय, new कीवर्ड का उपयोग करने के बजाय, लिटरल का उपयोग करके घोषित करना चाहिए।



उपरोक्त स्रोत कोड केवल एक उदाहरण का उपयोग करता है। इसके अलावा, इस पद्धति का उपयोग करके, यह सुनिश्चित किया जाता है कि एक ही JVM में "hi" स्ट्रिंग लिटरल का उपयोग करने वाले सभी कोड समान ऑब्जेक्ट का पुन: उपयोग करते हैं। ऐसा Java स्थिरांक पूल की विशेषता के कारण है।


new Boolean() का उपयोग

उपरोक्त कोड स्ट्रिंग को पैरामीटर के रूप में लेने वाले कंस्ट्रक्टर के माध्यम से बूलियन इंस्टेंस बना रहा है। बूलियन में केवल सही या गलत होता है, और हर बार इंस्टेंस बनाना मेमोरी की बर्बादी है। इसलिए, Boolean.valueOf() नामक स्थिर फैक्ट्री मेथड का उपयोग करना बेहतर है।



String.matches() का उपयोग

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



हालांकि, String.matches() प्रदर्शन के मामले में समस्याग्रस्त विधि है। यह विधि आंतरिक रूप से नियमित अभिव्यक्ति पैटर्न इंस्टेंस बनाती है, जिसका उपयोग एक बार किया जाता है और फिर तुरंत कचरा संग्रह का लक्ष्य बन जाता है, और यदि नियमित अभिव्यक्ति का बार-बार उपयोग किया जाता है, तो समान पैटर्न इंस्टेंस बनाया और त्याग दिया जाता है, जिससे लागत बढ़ जाती है। इसलिए, पैटर्न इंस्टेंस को पहले से कैश करना और बाद में isRomanNumeral() विधि को कॉल करते समय उस इंस्टेंस का पुन: उपयोग करना बेहतर है।



**ध्यान दें**

उपरोक्त सभी उदाहरणों में, जब अनावश्यक ऑब्जेक्ट को कैश किया जाता है, तो सभी को अपरिवर्तनीय ऑब्जेक्ट के रूप में बनाया जाता है। ऐसा इसलिए है क्योंकि उन्हें पुन: उपयोग करना सुरक्षित है। हालांकि, अपरिवर्तनीय ऑब्जेक्ट का पुन: उपयोग करने का यह अंतर्ज्ञान कभी-कभी विपरीत होता है।


एडेप्टर (व्यू) एक ऑब्जेक्ट है जो वास्तविक कार्य को बैकएंड ऑब्जेक्ट को सौंपता है और स्वयं एक दूसरा इंटरफ़ेस की भूमिका निभाता है। एडेप्टर को केवल बैकएंड ऑब्जेक्ट का प्रबंधन करने की आवश्यकता होती है, इसलिए प्रत्येक बैकएंड ऑब्जेक्ट के लिए केवल एक एडेप्टर बनाया जाना चाहिए।


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


ऐसा इसलिए है क्योंकि लौटाया गया Set इंस्टेंस परिवर्तनशील हो सकता है, लेकिन यह जो कार्य करता है वह समान है, और सभी Set इंस्टेंस Map इंस्टेंस का प्रतिनिधित्व करते हैं। इसलिए, भले ही keySet() कई व्यू ऑब्जेक्ट बनाता है, इससे कोई फर्क नहीं पड़ता, और ऐसा करने का कोई फायदा नहीं है।



इसलिए, यदि आप names1 इंस्टेंस को संशोधित करते हैं, तो names2 इंस्टेंस भी प्रभावित होगा।


हालांकि, व्यक्तिगत रूप से, मुझे लगता है कि keySet() विधि का रिटर्न मान डिफेंसिव कॉपी का उपयोग करके हर बार एक नया ऑब्जेक्ट लौटाना चाहिए। यदि keySet() विधि से प्राप्त Set इंस्टेंस का उपयोग कहीं और किया जा रहा है और उस इंस्टेंस की स्थिति को बदलने वाला कोई कोड है, तो वर्तमान में उपयोग किए जा रहे Set इंस्टेंस और Map इंस्टेंस के मानों पर विश्वास करना मुश्किल हो जाएगा।


इसके अलावा, ऐसे वातावरण में जहां keySet() का अत्यधिक उपयोग नहीं किया जाता है, Set इंटरफ़ेस का हर बार निर्माण प्रदर्शन को गंभीर रूप से प्रभावित नहीं करेगा। इसके बजाय, Set इंटरफ़ेस को अपरिवर्तनीय ऑब्जेक्ट के रूप में बनाना और रखरखाव को सुरक्षित बनाना बेहतर है।


ऑटो बॉक्सिंग

ऑटो बॉक्सिंग एक तकनीक है जो प्रोग्रामर को मूल प्रकार और रैपर प्रकार को मिलाकर उपयोग करने पर स्वचालित रूप से एक दूसरे में परिवर्तित कर देती है। हालाँकि, ऑटो बॉक्सिंग मूल प्रकार और रैपर प्रकार के बीच अंतर को धुंधला कर देता है, लेकिन इसे पूरी तरह से समाप्त नहीं करता है।



तार्किक रूप से, इसमें कोई समस्या नहीं है, लेकिन यह प्रदर्शन के मामले में बहुत अकुशल कोड है। इसका कारण sum के प्रकार और for लूप के अंदर i के प्रकार में है।


sum का प्रकार Long है, और i का प्रकार long है। दूसरे शब्दों में, जब long प्रकार का i पुनरावृति करते समय sum में जोड़ा जाता है, तो हर बार एक नया Long इंस्टेंस बनाया जाता है। नतीजतन, रैपर प्रकार की तुलना में मूल प्रकार का उपयोग करना और अनपेक्षित ऑटो बॉक्सिंग से सावधान रहना महत्वपूर्ण है।


जिसे गलत नहीं समझना चाहिए

अनावश्यक ऑब्जेक्ट निर्माण से बचने के निर्देश को केवल इस तरह से नहीं समझना चाहिए कि ऑब्जेक्ट निर्माण की लागत अधिक है, इसलिए इससे बचना चाहिए।


विशेष रूप से, आजकल JVM में, छोटे ऑब्जेक्ट जो अनावश्यक रूप से बनाए गए हैं, उन्हें बनाना और पुनः प्राप्त करना कोई बड़ी समस्या नहीं है। इसलिए, डेटाबेस कनेक्शन जैसे ऑब्जेक्ट जिनकी लागत बहुत अधिक होती है, को छोड़कर, कस्टम ऑब्जेक्ट पूल न बनाएं।


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


स्रोत

टिप्पणियाँ0

[गैर-तकनीकी, डेवलपर के रूप में जीवित रहना] 14. नव नियुक्त डेवलपर अक्सर पूछे जाने वाले तकनीकी साक्षात्कार सामग्री सारांशनव नियुक्त डेवलपर साक्षात्कार में अक्सर पूछे जाने वाले तकनीकी प्रश्न (मेमोरी क्षेत्र, डेटा संरचना, डेटाबेस आदि) को संक्षेप में प्रस्तुत किया गया है। डेवलपमेंट इंटरव्यू की तैयारी में यह मददगार होगा।
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자
투잡뛰는 개발 노동자

April 3, 2024

29 नवंबर 2024 की लेट ब्रेकिंग न्यूज़: Replit का पेड सब्सक्रिप्शन / अच्छी सॉफ्टवेयर डेवलपमेंट आदतें29 नवंबर 2024 को लिखे गए इस ब्लॉग पोस्ट में Replit के पेड सब्सक्रिप्शन के अनुभव को साझा किया गया है और अच्छी सॉफ्टवेयर डेवलपमेंट आदतों के 10 सुझाव दिए गए हैं। इसमें कुशल कोडिंग और रिफैक्टरिंग रणनीतियाँ, टेस्टिंग के महत्व आदि पर चर्चा की गई है।
Charles Lee
Charles Lee
Charles Lee
Charles Lee

November 29, 2024

2024-11-19 जीवन में रुचि रखने वाली विविध सामग्री: समाचार / TDD / AI / डेटा विश्लेषण2024 नवंबर 19 को लिखा गया दैनिक अवलोकन रिकॉर्ड है। इसमें समाचार, TDD, AI और डेटा विश्लेषण से संबंधित सामग्री शामिल है। शेयर बाजार, क्रिप्टोकरेंसी के रुझान, AI के भविष्य के पूर्वानुमान आदि जैसी विभिन्न जानकारियों का संक्षेप में सारांश दिया गया है।
Charles Lee
Charles Lee
Charles Lee
Charles Lee

November 19, 2024

2024-11-16 विभिन्न विषयों में रुचि: ब्लॉग की शुरुआत2024 के नवंबर 16 को लिखे गए इस ब्लॉग पोस्ट में LeetCode (लीटकोड) समस्याओं के समाधान, वीडियो निर्माण प्रक्रिया और भविष्य की योजनाओं (जैसे, elice.io पर अध्ययन) का विवरण दिया गया है।
Charles Lee
Charles Lee
Charles Lee
Charles Lee

November 16, 2024

2024-11-18 जीवन में रुचि रखने वाली विविध सामग्री: मैं क्या करके आनंद लेता हूँ?यह ब्लॉग पोस्ट 18 नवंबर, 2024 को लिखी गई थी। इसमें लेखक के शौक, निवेश, शिक्षा आदि विभिन्न प्रकार के दैनिक जीवन और स्वचालन के माध्यम से कार्य कुशलता में वृद्धि पर विचार शामिल हैं।
Charles Lee
Charles Lee
Charles Lee
Charles Lee

November 19, 2024

जेनेरिक का उपयोग करके अपरिवर्तनीय मान प्राप्त करनाटाइपस्क्रिप्ट 5.0 के नए कीवर्ड का उपयोग करके जेनेरिक में अपरिवर्तनीय मानों को आसानी से पास करने का तरीका बताया गया है। यह सरणी या लिटरल प्रकार के लिए भी उपयोग किया जा सकता है और इससे लाइब्रेरी विकास और उपयोगकर्ता अनुभव में सुधार होता है।
Sunrabbit
Sunrabbit
Sunrabbit
Sunrabbit

October 30, 2024