![translation](https://cdn.durumis.com/common/trans.png)
यह एक AI अनुवादित पोस्ट है।
भाषा चुनें
durumis AI द्वारा संक्षेपित पाठ
- new कीवर्ड का उपयोग करके अनावश्यक रूप से ऑब्जेक्ट बनाने से मेमोरी की बर्बादी होती है, इसलिए लिटरल का उपयोग करना या स्टैटिक फैक्ट्री मेथड का उपयोग करना बेहतर होता है।
- String.matches() मेथड आंतरिक रूप से Pattern इंस्टेंस बनाता है और उसे छोड़ देता है, इसलिए दोहराए जाने पर यह प्रदर्शन में गिरावट का कारण बन सकता है, और कैशिंग करके पुन: उपयोग करना अधिक कुशल होता है।
- ऑटो बॉक्सिंग एक स्वचालित रूपांतरण सुविधा है जो मूल प्रकार और रैपर प्रकार का उपयोग करते समय होती है, लेकिन अनपेक्षित ऑटो बॉक्सिंग प्रदर्शन में गिरावट का कारण बन सकता है, इसलिए रैपर प्रकार के बजाय मूल प्रकार का उपयोग करना बेहतर होता है।
अनावश्यक ऑब्जेक्ट बनाने के मामले
new String() का उपयोग
String a = new String("hi");
String b = new String("hi");
स्ट्रिंग a, b, c सभी "hi" स्ट्रिंग रखते हैं। लेकिन, इन तीन स्ट्रिंग्स द्वारा संदर्भित पते अलग-अलग हैं, इसलिए समान डेटा के लिए अलग-अलग मेमोरी आवंटित करने से बर्बादी होती है।
इसलिए, स्ट्रिंग की घोषणा करते समय, हमें new कीवर्ड का उपयोग नहीं करना चाहिए, बल्कि इसे लिटरल के रूप में घोषित करना चाहिए।
String a = "hi";
String b = "hi";
उपरोक्त स्रोत कोड केवल एक इंस्टेंस का उपयोग करता है। इसके अलावा, इस पद्धति का उपयोग करने से, यह सुनिश्चित किया जाता है कि JVM के भीतर "hi" स्ट्रिंग लिटरल का उपयोग करने वाला कोई भी कोड एक ही ऑब्जेक्ट का पुन: उपयोग करता है। ऐसा इसलिए है क्योंकि यह जावा स्थिर पूल की विशेषता के कारण है।
new Boolean() का उपयोग
उपरोक्त कोड कंस्ट्रक्टर के माध्यम से Boolean इंस्टेंस बना रहा है जो स्ट्रिंग को पैरामीटर के रूप में लेता है। Boolean के केवल true या false मौजूद हैं, हर बार इंस्टेंस बनाना मेमोरी की बर्बादी है। इसलिए, Boolean.valueOf() नामक स्टेटिक फ़ैक्टरी विधि का उपयोग करना बेहतर है।
String.matches() का उपयोग
जब निर्माण लागत अधिक होती है, तो कैशिंग और पुन: उपयोग करना बेहतर होता है, लेकिन हम हमेशा अपने द्वारा बनाए जा रहे ऑब्जेक्ट की लागत नहीं जान सकते। उदाहरण के लिए, मान लीजिए कि हम एक विधि लिखना चाहते हैं जो जांचती है कि दी गई स्ट्रिंग एक मान्य रोमन अंक है या नहीं, तो सबसे आसान तरीका है कि नियमित अभिव्यक्ति का उपयोग करें, जैसा कि नीचे दिखाया गया है।
public static boolean isRomanNumeral(String s) {
return s.matches("^(?=.)M*(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
हालांकि, String.matches() प्रदर्शन के मामले में एक समस्याग्रस्त विधि है। यह विधि आंतरिक रूप से नियमित अभिव्यक्ति के लिए Pattern इंस्टेंस बनाती है, जो एक बार उपयोग किए जाने के बाद, तुरंत कचरा संग्रह का लक्ष्य बन जाता है। यदि उस नियमित अभिव्यक्ति का बार-बार उपयोग किया जाता है, तो समान Pattern इंस्टेंस बनाए जाने और छोड़ दिए जाने की लागत बढ़ जाती है। इसलिए, Pattern इंस्टेंस को पहले से कैश करना बेहतर है, और जब भी isRomanNumeral() विधि को बुलाया जाता है, तो उस इंस्टेंस का पुन: उपयोग करें।
public class RomanNumerals {
private static final Pattern ROMAN = Pattern.compile(
"^(?=.)M*(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
public static boolean isRomanNumeral(String s) {
return ROMAN.matcher(s).matches();
}
ध्यान दें
उपरोक्त सभी उदाहरणों में, अनावश्यक ऑब्जेक्ट को कैश करते समय, हमने सभी को अपरिवर्तनीय ऑब्जेक्ट बनाया। ऐसा इसलिए है क्योंकि पुन: उपयोग करने पर यह सुरक्षित है। लेकिन, अपरिवर्तनीय ऑब्जेक्ट के पुन: उपयोग करने के बारे में अंतर्ज्ञान के खिलाफ कुछ मामले हैं।
एडॉप्टर (व्यू) एक ऐसा ऑब्जेक्ट है जो वास्तविक काम को बैकएंड ऑब्जेक्ट को सौंपता है, और खुद दूसरे इंटरफ़ेस की भूमिका निभाता है। एडॉप्टर को केवल बैकएंड ऑब्जेक्ट का प्रबंधन करना पड़ता है, इसलिए बैकएंड ऑब्जेक्ट के लिए केवल एक एडॉप्टर बनाने की आवश्यकता है।
उदाहरण के लिए, Map इंटरफ़ेस की keySet() विधि Map ऑब्जेक्ट के अंदर मौजूद सभी कुंजियों को रखने वाला एक Set दृश्य देता है। उपयोगकर्ता यह सोच सकता है कि जब भी वह keySet() विधि को कॉल करता है, तो एक नया Set इंस्टेंस बनाया जाता है, लेकिन वास्तव में, JDK कार्यान्वयन को देखते हुए, यह हर बार समान परिवर्तनशील Set इंस्टेंस देता है।
ऐसा इसलिए है क्योंकि लौटाए गए Set इंस्टेंस परिवर्तनशील हैं, लेकिन वे सभी समान कार्य करते हैं, और सभी Set इंस्टेंस Map इंस्टेंस का प्रतिनिधित्व करते हैं। इसलिए, भले ही keySet() कई दृश्य ऑब्जेक्ट बनाता है, इसे करने की आवश्यकता नहीं है, न ही कोई लाभ है।
public class UsingKeySet {
public static void main(String[] args) {
Map menu = new HashMap<>();
menu.put("Burger", 8);
menu.put("Pizza", 9);
Set names1 = menu.keySet();
Set names2 = menu.keySet();
names1.remove("Burger");
System.out.println(names1.size()); // 1
System.out.println(names2.size()); // 1
}
इसलिए, अगर हम names1 इंस्टेंस को संशोधित करते हैं, तो names2 इंस्टेंस भी प्रभावित होगा।
हालांकि, व्यक्तिगत रूप से, मेरा मानना है कि keySet() विधि के रिटर्न मान को रक्षात्मक प्रतिलिपि का उपयोग करके हर बार एक नया ऑब्जेक्ट वापस करना चाहिए। अगर keySet() विधि द्वारा प्राप्त Set इंस्टेंस का कहीं और उपयोग किया जा रहा है, और इस इंस्टेंस की स्थिति को बदलने वाला कोई कोड है, तो वर्तमान में उपयोग किए जा रहे Set इंस्टेंस और Map इंस्टेंस के मान पर भरोसा नहीं किया जा सकता है।
इसके अलावा, keySet() का अत्यधिक उपयोग करने वाले वातावरण के अलावा, हर बार Set इंटरफ़ेस बनाए जाने से प्रदर्शन पर घातक प्रभाव नहीं पड़ता है। बेहतर होगा कि Set इंटरफ़ेस को अपरिवर्तनीय ऑब्जेक्ट बनाया जाए ताकि स्थिरता सुनिश्चित हो सके।
ऑटो बॉक्सिंग
ऑटो बॉक्सिंग एक तकनीक है जो प्रोग्रामर को मूल प्रकार और रैपर प्रकार को मिलाकर उपयोग करने की अनुमति देती है, स्वचालित रूप से आपस में परिवर्तित होती है। लेकिन ऑटो बॉक्सिंग मूल प्रकार और रैपर प्रकार के बीच के अंतर को धुंधला कर देता है, इसे पूरी तरह से खत्म नहीं करता है।
public static long sum() {
Long sum = 0L;
for (long i = 0; i <= Integer.MAX_VALUE; i++) {
sum += i;
}
return sum;
तार्किक रूप से कोई समस्या नहीं है, लेकिन यह प्रदर्शन के मामले में बहुत अक्षम कोड है। इसका कारण sum के प्रकार और for लूप के अंदर मौजूद i के प्रकार में है।
sum का प्रकार Long है, और i का प्रकार long है। दूसरे शब्दों में, long प्रकार का i, sum में जोड़े जाने पर, हर बार जब लूप चलता है, तो एक नया Long इंस्टेंस बनाता है। परिणामस्वरूप, रैपर प्रकार की तुलना में मूल प्रकार का उपयोग करना और अनजाने में ऑटो बॉक्सिंग से बचना चाहिए।
समझ में नहीं आने वाली बातें
अनावश्यक ऑब्जेक्ट निर्माण से बचने के बारे में केवल ऑब्जेक्ट निर्माण की लागत अधिक होने के कारण इससे बचना चाहिए, ऐसा नहीं है।
विशेष रूप से आज के JVM में, अनावश्यक रूप से बनाए गए छोटे ऑब्जेक्ट को बनाने और पुनः प्राप्त करने का काम बहुत अधिक बोझ नहीं है। इसलिए, डेटाबेस कनेक्शन की तरह बहुत अधिक लागत वाले ऑब्जेक्ट के अलावा, कस्टम ऑब्जेक्ट पूल न बनाएं।
इसके अलावा, याद रखें कि जब आप ऑब्जेक्ट को पुन: उपयोग करते हैं तो रक्षात्मक प्रतिलिपि की आवश्यकता होती है, तो पुन: उपयोग करने से होने वाला नुकसान, अनावश्यक रूप से बनाए गए ऑब्जेक्ट के बार-बार बनाए जाने से होने वाले नुकसान से कहीं अधिक होता है। बार-बार निर्माण के दुष्प्रभाव केवल कोड के रूप और प्रदर्शन को प्रभावित करते हैं, लेकिन अगर रक्षात्मक प्रतिलिपि विफल हो जाती है, तो यह सीधे बग्स और सुरक्षा समस्याओं की ओर ले जाता है।