2008-09-26 9 views
186

.NET में सबसे लंबी स्ट्रिंग क्या बनाई जा सकती है? जहां तक ​​मैं देख सकता हूं, String वर्ग के लिए दस्तावेज़ इस प्रश्न पर चुप हैं, इसलिए एक आधिकारिक उत्तर के लिए आंतरिक के कुछ ज्ञान की आवश्यकता हो सकती है। 64-बिट सिस्टम पर अधिकतम परिवर्तन होगा?.NET स्ट्रिंग की अधिकतम संभव लंबाई क्या है?

[यह व्यावहारिक उपयोग के लिए की तुलना में जिज्ञासा के लिए अधिक से पूछा जाता है - मैं किसी भी कोड विशाल तार का उपयोग करता है बनाने के लिए इरादा नहीं है]

उत्तर

270

सैद्धांतिक सीमा 2,147,483,647 हो सकती है, लेकिन व्यावहारिक सीमा कहीं भी नहीं है। चूंकि .NET प्रोग्राम में कोई भी ऑब्जेक्ट 2 जीबी से अधिक नहीं हो सकता है और स्ट्रिंग प्रकार यूनिकोड (प्रत्येक वर्ण के लिए 2 बाइट्स) का उपयोग करता है, तो आप सबसे अच्छा कर सकते हैं 1,073,741,823, लेकिन आप कभी भी इसे आवंटित करने में सक्षम नहीं होने की संभावना है 32-बिट मशीन।

यह उन स्थितियों में, जहां "If you have to ask, you're probably doing something wrong."

+7

यह सही उत्तर है। स्ट्रिंग लम्बाई निकालने के लिए पर्याप्त आवंटित करने में सक्षम होने से पहले आपको स्मृति से बाहर होने की अधिक संभावना है। एक ताजा बूट पर आप यहां वर्णित 2 जीबी (1 एम अक्षरों के साथ) आवंटित करने में सक्षम हो सकते हैं, लेकिन यह सब कुछ है। –

+4

मानते हैं कि आपका "कोई भी ऑब्जेक्ट 2 जीबी से अधिक नहीं हो सकता है" दावा सटीक है, यह सैद्धांतिक सीमा के साथ-साथ व्यावहारिक है - स्ट्रिंग लम्बाई पर बाधा कुल ऑब्जेक्ट आकार होगी, न कि लंबाई फ़ील्ड की क्षमता। – McKenzieG1

+10

यदि कोई मेरी सटीक मान में रूचि रखता है, तो मेरी 64-बिट मशीन पर यह 1,073,741,791 (1024 · 1024 · 1024 - 33) वर्ण है। यह भी देखें [बाइट [] '] (http://stackoverflow.com/q/6616739/41071) के सटीक अधिकतम आकार के बारे में मेरा संबंधित प्रश्न। – svick

47

के बाद से System.String की लंबाई संपत्ति कोई Int32 है, मुझे लगता है होगा कि अधिकतम लंबाई 2,147,483,647 वर्ण (अधिकतम Int32 आकार) होगी। यदि यह लंबे समय तक अनुमति देता है तो आप लंबाई की जांच नहीं कर सकते क्योंकि यह असफल हो जाएगा।

+10

+1 अच्छी कटौती –

+2

@ एम.डमंडसन: मैं वास्तव में विश्वास नहीं कर रहा हूं। एक [सरणी] (https://msdn.microsoft.com/en-us/library/system.array%28v=vs.110%29.aspx) उदाहरणों के लिए 'लांग लम्बाई' भी है और एक स्ट्रीम 'लंबे समय तक उपयोग करती है लंबाई के रूप में। यद्यपि यह वैध उत्तर है, लेकिन यह मापने का एक सही तरीका नहीं है। –

+0

लेकिन पहले दो बिट्स ASCII/non-ASCII संकेत के लिए उपयोग किए जाते हैं [इस आलेख] (https://www.codeproject.com/Articles/3377/Strings-UNDOCUMENTED) कहते हैं, तो यह 2^30 = 1 होना चाहिए 073 741 824 – Saito

0

के बाद से String.Length एक पूर्णांक इसके आकार Int32.MaxValue यूनिकोड वर्णों तक सीमित है (जो Int32 के लिए एक उपनाम है);)

60

मेरी अत्यधिक वैज्ञानिक और सही प्रयोग के आधार पर यह मेरी मशीन पर बाहर सबसे ऊपर है 1,000,000,000 वर्णों से पहले (मैं एक बेहतर पिनपॉइंट प्राप्त करने के लिए अभी भी नीचे कोड चला रहा हूं)। अद्यतन: कुछ घंटों के बाद, मैंने छोड़ दिया है। अंतिम परिणाम: 100,000,000 वर्णों से बहुत अधिक जा सकते हैं, तुरंत सिस्टम.ऑटऑफमेमरी अपवाद 1000,000,000 वर्णों पर दिया गया।

using System; 
using System.Collections.Generic; 

public class MyClass 
{ 
    public static void Main() 
    { 
     int i = 100000000; 
     try 
     { 
      for (i = i; i <= int.MaxValue; i+= 5000) 
      { 
       string value = new string('x', i); 
       //WL(i); 
      } 
     } 
     catch (Exception exc) 
     { 
      WL(i); 
      WL(exc); 
     } 
     WL(i); 
     RL(); 
    } 

    #region Helper methods 

    private static void WL(object text, params object[] args) 
    { 
     Console.WriteLine(text.ToString(), args); 
    } 

    private static void RL() 
    { 
     Console.ReadLine(); 
    } 

    private static void Break() 
    { 
     System.Diagnostics.Debugger.Break(); 
    } 

    #endregion 
} 
+25

यहां एक बाइनरी खोज लागू करने से शायद आपको यह उत्तर बहुत तेज़ी से ढूंढने में मदद मिलेगी ... – Mario

+24

+1 परीक्षण संचालित उत्तर के उपयोग के लिए +1। –

1

200 megs ... जिस पर अपने अनुप्रयोग एक आभासी रोकने के लिए grinds बात में से एक है, एक कार्यक्रम के काम करने के लिए सेट स्मृति के बारे में है, और ओ/s शुरू होता है आप की तरह कार्य करने के लिए रीबूट करने की आवश्यकता होगी।

static void Main(string[] args) 
{ 
    string s = "hello world"; 
    for(;;) 
    { 
     s = s + s.Substring(0, s.Length/10); 
     Console.WriteLine(s.Length); 
    } 
} 

12 
13 
14 
15 
16 
17 
18 
... 
158905664 
174796230 
192275853 
211503438 
+4

मुझे यकीन नहीं है कि आप जो वास्तव में एक बहुत बड़ी स्ट्रिंग बनाने से प्राप्त करेंगे, वह वही है जो आप उन्हें देखकर देख रहे हैं और उन्हें संयोजित कर रहे हैं। – Casey

20

देर इस विषय के लिए आ रहा किसी के लिए, मैं देख सकता था कि hitscan के किसी से पूछना उन्हें क्या करना चाहिए कारण हो सकता है "आप शायद ऐसा नहीं करना चाहिए" ...

StringBuilder वर्ग अक्सर है एक आसान प्रतिस्थापन। stream-based classes में से एक पर विचार करें, खासकर यदि आपका डेटा किसी फ़ाइल से आ रहा है।

एस = एस + "सामान" के साथ समस्या यह है कि इसे डेटा को पकड़ने के लिए एक पूरी तरह से नया क्षेत्र आवंटित करना होगा और उसके बाद सभी पुराने डेटा को कॉपी करना होगा और साथ ही साथ नई सामग्री - प्रत्येक और प्रत्येक लूप इत्यादि। तो एस = एस + "सामान" के साथ 5 बाइट्स से 1 मिलियन जोड़ना बेहद महंगा है। यदि आप चाहते हैं कि केवल 5 बाइट्स अंत में लिखें और अपने प्रोग्राम के साथ आगे बढ़ें तो आपको एक कक्षा चुननी होगी जो विकास के लिए कुछ जगह छोड़ दे।

StringBuilder sb = new StringBuilder(5000); 
for (; ;) 
    { 
     sb.Append("stuff"); 
    } 

StringBuilder auto-grow by doubling जब यह सीमा तक नहीं पहुंच रहा है होगा। तो आप शुरुआत में एक बार विकास दर्द देखेंगे, एक बार 5000 बाइट्स पर, फिर से 10000 पर, फिर 20000 पर। तारों को जोड़ना हर लूप पुनरावृत्ति को दर्द देगा।

+4

यह भी ध्यान देने योग्य है कि स्ट्रिंगबिल्डर आपको प्रारंभिक आकार सेट करने की अनुमति देता है। उपयोगी अगर आप जानते हैं कि आप समय से पहले 10,000,000 प्रविष्टियों का उपयोग करने जा रहे हैं, जिससे आप कुछ क्रंच को अनदेखा कर सकते हैं। –

+2

+1 प्रश्न के माध्यम से देखने और अच्छे डिजाइन के जवाब देने के लिए। तुलनात्मक रूप से, "यह आपकी स्ट्रिंग कितनी बड़ी हो सकती है इससे पहले कि यह उड़ाए", "अगर आपको वास्तव में बहुत सारे टेक्स्ट स्टोर करने की ज़रूरत है, तो इसका उपयोग करें ..." – StevoInco

5

स्ट्रिंग्स पूर्णांक द्वारा सीमित नहीं हैं जैसा कि आमतौर पर माना जाता है

मेमोरी प्रतिबंध एक तरफ, तार, अधिक से अधिक 2 (1.073.741.824) वर्ण नहीं हो सकते क्योंकि एक 2GB सीमा माइक्रोसॉफ्ट CLR (सामान्य भाषा द्वारा लगाया गया है क्रम)।

उम्मीद है कि यह भविष्य में बदल सकता है।

0

ध्यान दें कि BinaryWriter.Write (स्ट्रिंग) स्ट्रिंग लंबाई को एक हस्ताक्षरित चार (एक बाइट) के रूप में लिखता है!

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