2011-09-25 15 views
5

जब मेरे पास 5 की क्षमता के साथ StringBuilder खाली है और मैं लिखता हूं "हैलो, दुनिया!" इसके लिए, सी # मानक StringBuilder की नई क्षमता निर्दिष्ट करता है? मेरे पास एक अस्पष्ट स्मृति है कि यह नई स्ट्रिंग की लंबाई से दोगुना है (प्रत्येक नई संलग्न स्ट्रिंग के साथ क्षमता बदलने से बचने के लिए)।स्ट्रिंगबिल्डर की क्षमता कैसे बदलती है?

+4

यह किसी भी मानक में निर्दिष्ट नहीं है, इसकी सिर्फ एक कार्यान्वयन विस्तार – BrokenGlass

+0

स्ट्रिंगबिल्डर सी # भाषा का हिस्सा नहीं है। यह .NET पुस्तकालयों का हिस्सा है। –

+0

संभावित डुप्लिकेट [स्ट्रिंगबिल्डर कैसे तय करता है कि इसकी क्षमता कितनी बड़ी होनी चाहिए?] (Http://stackoverflow.com/questions/4495855/how-does-the-stringbuilder-decide-how-large-its-capacity-should -be) – bzlm

उत्तर

15

निर्भर करता है कि .NET का कौन सा संस्करण आप बात कर रहे हैं। .NET 4 से पहले, स्ट्रिंगबिल्डर ने standard .NET strategy का उपयोग किया, आंतरिक बफर की क्षमता को हर बार बढ़ाए जाने की क्षमता को दोगुना कर दिया।

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

public StringBuilder(int capacity) { ... m_ChunkChars = new char[capacity]; ... }

तो, अगर क्षमता 40K वर्ण से छोटी है यह छोटी सी वस्तु ढेर पर चला जाता है:

+0

यह हमारे लिए गड़बड़ हो गया जब हमने अपने उत्पाद को .NET 3.5 से .Net 4.5 में अपग्रेड किया। हम स्ट्रिंग बिल्डर ऑब्जेक्ट का उपयोग इंटरपॉप के माध्यम से मूल एपीआई कॉल के पैरामीटर के रूप में कर रहे थे। इसके परिणामस्वरूप प्रक्रिया को क्रैश करने के कारण बफर ओवररन समस्या उत्पन्न हुई। जब देशी एपीआई लंबे तारों को वापस कर रहा था तो हीप मेमोरी दूषित हो रही थी। हमने कन्स्ट्रक्टर में स्पष्ट क्षमता प्रदान करना शुरू कर दिया ताकि बफर लंबे तारों का ख्याल रख सके। आश्चर्यजनक रूप से यह लंबे तारों के लिए भी पहले तोड़ना चाहिए था लेकिन कभी रिपोर्ट नहीं हुई। इंटरऑप परत .NET 3.5 में कुछ चाल करता है जब हम स्ट्रिंग बिल्डर का उपयोग मूल एपीआई के लिए बफर के रूप में करते हैं? – RBT

+0

जो किसी भी रनटाइम संस्करण में जीसी ढेर को दूषित करता है। इस तरह के भ्रष्टाचार की आवश्यकता नहीं है, आपको भाग्यशाली होना है। निश्चित रूप से, आप .NET 4 –

5

सी # मानक बीसीएल लाइब्रेरी कक्षा के व्यवहार को निर्दिष्ट नहीं करेगा क्योंकि इसका भाषा विनिर्देशन से कोई लेना देना नहीं है।

जहां तक ​​मुझे पता है कि वास्तविक व्यवहार किसी भी विनिर्देश में परिभाषित नहीं है और कार्यान्वयन विशिष्ट है।

AFAIK, मौजूदा क्षमता तक पहुंचने के बाद एमएस कार्यान्वयन क्षमता को दोगुना कर देगा।

this और this पिछले SO प्रश्न देखें।


अद्यतन:

यह .NET 4.0 में बदल दिया गया है। द्वारा his answer में वर्णित अनुसार। अब ropes का उपयोग किया जाता है, एक समय में अतिरिक्त 8000 अक्षर जोड़ते हैं।

StringBuilder गतिशील और अधिक स्थान की जरूरत पड़ने पर आवंटित करता है और उसके अनुसार क्षमता बढ़ जाती है:

MSDN, तथापि करते रहे कि वास्तविक व्यवहार कार्यान्वयन विशिष्ट बहुत सावधान है। प्रदर्शन कारणों से, एक स्ट्रिंगबिल्डर आवश्यकतानुसार अधिक स्मृति आवंटित कर सकता है। आवंटित स्मृति की मात्रा कार्यान्वयन-विशिष्ट है।

+2

हम अब डबल-पूर्ण-पूर्ण रणनीति का उपयोग नहीं करते हैं। –

+1

@Eric - मुझे सही करने के लिए धन्यवाद। हंस से जवाब और जवाब ने मुझे और विस्तार दिया। – Oded

-1

न्यू StringBuilder (.NET 4.5 या अधिक) एक आंतरिक बफर m_ChunkChars क्षमता पैरामीटर द्वारा अनुरोध आवंटित करता है। हालांकि (प्रचलित धारणा के विपरीत), StringBuilder अभी भी बड़े वस्तु ढेर पर आवंटित करेगा अगर, बाद में, हम sb.Append(...some string larger than 40K chars...); फोन एक संभव फिक्स यहां पाया जा सकता: https://github.com/amikunov/Large-Object-Heap-Fix-For-.NET-String-Builder

+1

में अधिक भाग्यशाली हो जाते हैं, इसमें सवाल पूछने के साथ कुछ भी नहीं है। – Servy

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