2012-03-03 12 views
56

संभव डुप्लिकेट:
Why can't strings be mutable in Java and .NET?
Why .NET String is immutable?कई प्रोग्रामिंग भाषाओं में स्ट्रिंग्स अपरिवर्तनीय क्यों हैं?

कई भाषाओं सी #, जावा, और अजगर के रूप में इस के लिए चुना है,। यदि यह स्मृति को बचाने या जैसे संचालन के लिए दक्षता हासिल करने का इरादा है, तो की तुलना करें, इसके साथ संयोजन और अन्य संशोधित संचालन पर क्या प्रभाव पड़ता है?

+1

http://stackoverflow.com/questions/2365272/why-net-string-is-immutable – Mehrdad

+17

सी ++ की 'std :: string' * अपरिवर्तनीय नहीं है। – fredoverflow

उत्तर

71

अपरिवर्तनीय प्रकार आम तौर पर एक अच्छी बात कर रहे हैं: (! आप कुछ है कि नहीं बदल सकते लॉक करने के लिए की जरूरत नहीं है)

  • वे संगामिति लिए बेहतर काम
  • वे त्रुटियों को कम: परिवर्तनशील वस्तुओं जोखिम रहता है जब आप इसकी अपेक्षा नहीं करते हैं तो इसे बदलने के लिए जो सभी प्रकार की अजीब बग ("दूरी पर कार्रवाई")
  • उन्हें सुरक्षित रूप से साझा किया जा सकता है (यानी एक ही ऑब्जेक्ट के एकाधिक संदर्भ) जो स्मृति खपत को कम कर सकते हैं और बेहतर कर सकते हैं कैश उपयोग।
  • शेयरिंग एक बहुत ही सस्ते ओ (1) ऑपरेशन की प्रतिलिपि बनाता है जब यह ओ (एन) होगा यदि आपको एक म्यूटेबल ऑब्जेक्ट की रक्षात्मक प्रति लेनी है। यह एक बड़ी बात है क्योंकि नकल एक अविश्वसनीय रूप से आम आपरेशन (जैसे जब भी आप मापदंडों के आसपास पास करना चाहते हैं ....)

नतीजतन, यह तार अपरिवर्तनीय बनाने के लिए एक बहुत ही उचित भाषा डिजाइन पसंद है है।

कुछ भाषाओं (विशेष रूप से कार्यात्मक भाषाएं जैसे हास्केल और क्लोजर) आगे बढ़ती हैं और सब कुछ अपरिवर्तनीय बनाती हैं। यदि आप अपरिवर्तनीयता के लाभ में रूचि रखते हैं तो यह enlightening video बहुत अधिक दिखता है।

अपरिवर्तनीय प्रकार के लिए मामूली कमियां के एक जोड़े हैं:

  • संचालन, जो एक बदली हुई स्ट्रिंग संयोजन की तरह और अधिक महंगा है क्योंकि आप नई वस्तुओं का निर्माण करने की आवश्यकता है बनाएँ। आम तौर पर लागत दो (अपरिवर्तनीय स्ट्रिंग्स को संयोजित करने के लिए ओ (एन + एम) होती है, हालांकि यदि आप पेड़-आधारित स्ट्रिंग डेटा स्ट्रक्चर का उपयोग करते हैं तो Rope जैसे यह ओ (लॉग (एम + एन)) के रूप में कम हो सकता है। इसके अलावा यदि आप वास्तव में स्ट्रिंग्स को कुशलता से जोड़ना चाहते हैं तो आप हमेशा जावा के StringBuilder जैसे विशेष टूल का उपयोग कर सकते हैं।
  • बड़ी स्ट्रिंग पर एक छोटे से बदलाव के परिणामस्वरूप बड़ी स्ट्रिंग की पूरी तरह से नई प्रतिलिपि बनाने की आवश्यकता हो सकती है, जो स्पष्ट रूप से स्मृति खपत को बढ़ाता है। ध्यान दें कि यह आमतौर पर कचरा-एकत्रित भाषाओं में एक बड़ा मुद्दा नहीं है क्योंकि पुरानी प्रति को कचरा इकट्ठा किया जाएगा यदि आप इसका संदर्भ नहीं रखते हैं।

कुल मिलाकर, अपरिवर्तनीयता के फायदे मामूली नुकसान से काफी अधिक हैं। यहां तक ​​कि यदि आप केवल प्रदर्शन में रूचि रखते हैं, तो प्रतिलिपि के फायदे और सस्तीता की सस्तीता आम तौर पर लॉकिंग और रक्षात्मक प्रतिलिपि के साथ उत्परिवर्तनीय लोगों की तुलना में अपरिवर्तनीय तारों को अधिक प्रदर्शनकारी बनाती है।

+2

अच्छे अंक। लेकिन, हर सिक्का के दो पक्ष होते हैं। आपने बस अपसाइड सूचीबद्ध किए हैं। डाउनसाइड्स के बारे में क्या? चूंकि यह अपरिवर्तनीय है, हम केवल दो तारों को एक दूसरे के लंबित करके दो तारों को संयोजित नहीं कर सकते हैं; हमें एक नई स्ट्रिंग भी बनाना है, यहां तक ​​कि यह मौजूदा स्ट्रिंग से केवल एक चर के रूप में छोटा है, जिसका अर्थ है स्मृति की सीपीयू-उपभोग आवंटन। – snowfox

+4

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

+0

मैंने अपना जवाब थोड़ा बढ़ाया है। लेकिन ध्यान दें कि विशेष रूप से आपके संलग्न उदाहरण के साथ, पुरानी अपरिवर्तनीय स्ट्रिंग आमतौर पर जीसीडी को बहुत जल्दी मिल जाएगी, इसलिए स्मृति उपयोग पर असर केवल अस्थायी है। – mikera

16

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

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

असल में, अपरिवर्तनीय डेटा उस कोड को बनाता है जो इस पर काम करता है जिसके बारे में कारण बनाना आसान है। यही कारण है कि पूरी तरह कार्यात्मक भाषा सब कुछ अपरिवर्तनीय रखने की कोशिश करती है।

3

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

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

+0

ग्रेट प्वाइंट। धन्यवाद। – snowfox

+0

"शाब्दिक" पूल केवल कुछ मामलों में उपयोग किया जाता है। संख्यात्मक रैपर वर्गों के लिए यह केवल एक निश्चित सीमा में संख्याओं के लिए उपयोग किया जाता है (int I think -128 से 127 तक) और केवल मुक्केबाजी संचालन करते समय (यानी नया इंटीजर (5) अभी भी एक नया 'इंटेगर' ऑब्जेक्ट बना देगा, लेकिन 'पूर्णांक एन = 5' इंटर्न पूल में 'इंटेगर' ऑब्जेक्ट का संदर्भ देगा)। 'स्ट्रिंग' के लिए, यह केवल वास्तविक अक्षर के साथ होता है; यदि आप गतिशील रूप से एक स्ट्रिंग बनाते हैं (उदाहरण के लिए 'स्ट्रिंग ए = "एक्स"; स्ट्रिंग बी = ए + "एबीसी";' (यहां बी ढेर पर है)) तो यह सामान्य ढेर पर एक नई वस्तु होगी जब तक कि आप जानबूझकर इसे 'String.intern()' के साथ प्रशिक्षित करें। –

+0

@ user1087373: मुझे नहीं लगता कि आपको यह जवाब स्वीकार करना चाहिए। यह कुछ भी नहीं बताता है। इसके विपरीत, यह गलत तर्क प्रदान करता है। – Nawaz

1

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

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