2010-03-24 11 views
10

मैं स्ट्रिंग इंटर्निंग को समझने की कोशिश कर रहा हूं और मेरे उदाहरण में ऐसा क्यों प्रतीत नहीं होता है। उदाहरण का बिंदु उदाहरण 1 को कम (बहुत कम स्मृति) का उपयोग करना है क्योंकि इसमें केवल स्मृति में 10 स्ट्रिंग होनी चाहिए। हालांकि, दोनों उदाहरणों के नीचे दिए गए कोड में लगभग समान मात्रा में स्मृति (वर्चुअल आकार और कार्य सेट) का उपयोग करें।सी # स्ट्रिंग इंटर्निंग

कृपया सलाह दें कि उदाहरण 1 बहुत कम स्मृति का उपयोग क्यों नहीं कर रहा है? धन्यवाद

उदाहरण 1:

 IList<string> list = new List<string>(10000); 

     for (int i = 0; i < 10000; i++) 
     { 
      for (int k = 0; k < 10; k++) 
      { 
       list.Add(string.Intern(k.ToString())); 
      } 

     } 

     Console.WriteLine("intern Done"); 
     Console.ReadLine(); 

उदाहरण 2:

 IList<string> list = new List<string>(10000); 

     for (int i = 0; i < 10000; i++) 
     { 
      for (int k = 0; k < 10; k++) 
      { 
       list.Add(k.ToString()); 
      } 

     } 

     Console.WriteLine("intern Done"); 
     Console.ReadLine(); 
+1

इस सवाल का एक तुम कल पूछा की तरह एक बहुत कुछ नहीं है? http://stackoverflow.com/questions/2502522/string-interning-should-this-code-only-create-10-strings-in-memory –

+0

हां एक जैसे, लेकिन – CodingThunder

उत्तर

2

msdnदूसरा से प्रशिक्षु के लिए,:

यहाँ एक उदाहरण एक अंतर दिखाने करता है। स्ट्रिंग ऑब्जेक्ट द्वारा उपयोग की जाने वाली मेमोरी को अभी भी आवंटित किया जाना चाहिए, भले ही स्मृति अंततः कचरा एकत्रित हो जाए।

16

समस्या यह है कि ToString (है) अभी भी एक नया स्ट्रिंग, और फिर यह प्रशिक्षु आवंटित करेगा। यदि कचरा कलेक्टर उन "अस्थायी" तारों को इकट्ठा करने के लिए नहीं चलता है, तो स्मृति उपयोग समान होगा।

इसके अलावा, आपके तारों की लंबाई बहुत कम है। 10,000 तार जो ज्यादातर एक वर्ण लंबे होते हैं, लगभग 20 केबी का स्मृति अंतर होता है जिसे आप शायद नोटिस नहीं करेंगे। लंबे तारों का उपयोग करने का प्रयास करें (या उनमें से अधिक) और मेमोरी उपयोग की जांच करने से पहले एक कचरा संग्रह करना। , आप पहली स्ट्रिंग बनाने चाहिए एक स्ट्रिंग

class Program 
{ 
    static void Main(string[] args) 
    { 
     int n = 100000; 

     if (args[0] == "1") 
      WithIntern(n); 
     else 
      WithoutIntern(n); 
    } 

    static void WithIntern(int n) 
    { 
     var list = new List<string>(n); 

     for (int i = 0; i < n; i++) 
     { 
      for (int k = 0; k < 10; k++) 
      { 
       list.Add(string.Intern(new string('x', k * 1000))); 
      } 
     } 

     GC.Collect(); 
     Console.WriteLine("Done."); 
     Console.ReadLine(); 
    } 

    static void WithoutIntern(int n) 
    { 
     var list = new List<string>(n); 

     for (int i = 0; i < n; i++) 
     { 
      for (int k = 0; k < 10; k++) 
      { 
       list.Add(new string('x', k * 1000)); 
      } 
     } 

     GC.Collect(); 
     Console.WriteLine("Done."); 
     Console.ReadLine(); 
    } 
} 
+2

विशिष्ट माइक्रो-ऑप्टिमाइज़ेशन जो बस नहीं करता दिखाओ कि यह क्या करना है। – TomTom

+0

जीसी के साथ समान परिणाम और बड़े तारों का उपयोग .... hrmmmm – CodingThunder

+0

@ टॉमटॉम: क्या? – CodingThunder

7

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

हालांकि, यदि आप उदाहरणों के लिए वास्तविक स्मृति उपयोग को देखते हैं तो आपको एक अंतर दिखाई देगा।

उदाहरण 1

0:005>!dumpheap -stat 
... 
00b6911c  137   4500 System.String 
0016be60  8  480188  Free 
00b684c4  14  649184 System.Object[] 
Total 316 objects 
0:005> !eeheap -gc 
Number of GC Heaps: 1 
generation 0 starts at 0x01592dcc 
generation 1 starts at 0x01592dc0 
generation 2 starts at 0x01591000 
ephemeral segment allocation context: none 
segment begin allocated  size 
01590000 01591000 01594dd8 0x00003dd8(15832) 
Large object heap starts at 0x02591000 
segment begin allocated  size 
02590000 02591000 026a49a0 0x001139a0(1128864) 
Total Size 0x117778(1144696) 
------------------------------ 
GC Heap Size 0x117778(1144696) 

उदाहरण 2

0:006> !dumpheap -stat 
... 
00b684c4  14  649184 System.Object[] 
00b6911c 100137  2004500 System.String 
Total 100350 objects 
0:006> !eeheap -gc 
Number of GC Heaps: 1 
generation 0 starts at 0x0179967c 
generation 1 starts at 0x01791038 
generation 2 starts at 0x01591000 
ephemeral segment allocation context: none 
segment begin allocated  size 
01590000 01591000 0179b688 0x0020a688(2139784) 
Large object heap starts at 0x02591000 
segment begin allocated  size 
02590000 02591000 026a49a0 0x001139a0(1128864) 
Total Size 0x31e028(3268648) 
------------------------------ 
GC Heap Size 0x31e028(3268648) 

आप दूसरे उदाहरण ऊपर उत्पादन से देख प्रबंधित ढेर के बारे में अधिक स्मृति का उपयोग करता है सकते हैं।

0

स्रोत:https://blogs.msdn.microsoft.com/ericlippert/2009/09/28/string-interning-and-string-empty/

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

उदाहरण:

object obj = "Int32"; 
string str1 = "Int32"; 
string str2 = typeof(int).Name; 

निम्नलिखित तुलना के उत्पादन:

Console.WriteLine(obj == str1); // true 
Console.WriteLine(str1 == str2); // true  
Console.WriteLine(obj == str2); // false !? 

Note1: वस्तुओं संदर्भ से तुलना कर रहे हैं।

नोट 2: टाइपऑफ (int) .नाम का प्रतिबिंब विधि द्वारा मूल्यांकन किया जाता है, इसलिए इसे संकलन समय पर मूल्यांकन नहीं किया जाता है। यहां ये तुलना संकलन समय पर की जाती है।

के परिणाम विश्लेषण:

  1. सच है क्योंकि वे दोनों एक ही शाब्दिक और होती है, इसलिए कोड उत्पन्न केवल एक ही वस्तु को संदर्भित "Int32" होगा। नोट देखें 1.

  2. सच है क्योंकि दोनों मानों की सामग्री की जांच की जाती है जो समान है।

  3. झूठी क्योंकि str2 और obj में एक ही शाब्दिक नहीं है। देखें नोट 2.

+1

कृपया एक से अधिक प्रश्नों के लिए एक ही उत्तर पोस्ट न करें। यदि प्रश्न मूल रूप से वही हैं, [उन्हें ध्वजांकित करें] (https://stackoverflow.com/privileges/flag-posts) डुप्लिकेट के रूप में। अन्यथा, प्रश्न के उत्तर को कस्टमाइज़ करें। –

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