2010-07-29 666 views
10

मुझे प्रति सेकंड लगभग 5 संदेश प्राप्त होते हैं। उनमें से हर एक स्ट्रिंग है, जो मैं एक मास्टर स्ट्रिंग के लिए जोड़ है कि सभी प्राप्त हुए संदेशों कास्ट्रिंगबिल्डर या + =

string _masterText = ""; 
    public void AddNewMessage(string text) // this is going to be call at least 5 times/second 
    { 
     _masterText += text;  
    } 

इस यह करने के लिए appropiated रास्ता नहीं है शामिल है? या मैं इस्तेमाल करना चाहिए बजाय StringBuilder, जैसे:

StringBuilder _masterText = new StringBuilder(); 
    public void AddNewMessage(string text) // this is going to be call at least 5 times/second 
    { 
     _masterText.Append(text); 
    } 

धन्यवाद

+0

मुझे लगता है कि उत्तर इस परिणामस्वरूप निर्भर करता है कि आप इसके परिणामस्वरूप _maseterText के साथ क्या करना चाहते हैं। –

+0

मैं इसे GUI – pedroruiz

उत्तर

15

स्ट्रिंगबिल्डर आमतौर पर बेहतर विकल्प माना जाता है, लेकिन इस मामले में मैं का उपयोग नहीं करता।

स्ट्रिंगबिल्डर के साथ भी, उस दर पर अंतर्निहित चरित्र बफर जल्द ही बड़े ऑब्जेक्ट हीप पर फंसने के लिए पर्याप्त होगा। यह किसी ऐसे एप्लिकेशन के स्वास्थ्य के लिए समस्याएं पैदा करेगा जो थोड़ी देर के लिए चलने की आवश्यकता है।

इसके बजाय, मैं System.Collections.Generic.List<string> का उपयोग करता हूं और प्रत्येक नए संदेश के लिए इसे .Add() विधि कहता हूं। इन संदेशों के साथ आप जो करते हैं उसके आधार पर आप एक और संग्रह प्रकार भी अधिक उपयुक्त हो सकते हैं (शायद Queue<string>), लेकिन यह वह दिशा है जिसे आपको जाना चाहिए। संग्रह का उपयोग करके, प्रत्येक व्यक्तिगत स्ट्रिंग द्वारा उपयोग की जाने वाली मेमोरी संग्रह ऑब्जेक्ट के आकार की ओर गिनती नहीं होगी। इसके बजाय, प्रत्येक स्ट्रिंग केवल संदर्भ के लिए कुछ बाइट जोड़ देगा। बड़े ऑब्जेक्ट हीप को कॉम्पैक्ट करने में समस्याएं चलाने में काफी समय लगेगा।

यदि आपको अभी भी संग्रह में स्विच करने के बाद समस्याएं हैं, तो आप स्ट्रीम का उपयोग कर सकते हैं और डिस्क पर तार लिख सकते हैं। इस तरह, आपके पास एक समय में रैम में एक से अधिक स्ट्रिंग नहीं होती है। अब, एकमात्र तरीका आपको समस्या है यदि व्यक्तिगत तार 85000 बाइट या बड़े हैं।

+0

में एक memoEdit (DevExpress) में दिखाऊंगा, यह एक अच्छा विचार होगा कि संदेश को हर घंटे या तो डिस्क पर डंप करने के लिए एक सैने स्तर पर मेमोरी उपयोग को रखें। इस संदेश के आधार पर आप संदेशों के भंडारण को प्रबंधित करने के लिए एक समर्पित धागा रखना चाहते हैं। – ChaosPandion

+0

यह पूरे दिन चलने वाला नहीं है, उपयोगकर्ता एप्लिकेशन लॉन्च करेगा और – pedroruiz

+0

@pedroruiz ठीक पर 5 मिनट तक चल रहा है, ठीक है। सूची और कतार अभी भी आसान और तेज़ हैं, और अभी भी इसे संभालने का सही तरीका है। –

3

हर 200 मि.से एक बहुत कर लगाने चुनाव नहीं है, भले ही stringbuilder हमेशा बेहतर है।

0

स्ट्रिंगबिल्डर आपका दोस्त है!

8

याद रखें कि String कक्षा अपरिवर्तनीय है। एक स्ट्रिंग को बदलना संभव नहीं है। जब आप तारों को "संयोजित" कर रहे हैं, तो आप वास्तव में एक नई स्ट्रिंग बना रहे हैं, और मूल स्ट्रिंग की सामग्री को कॉपी कर रहे हैं, फिर अपनी नई स्ट्रिंग की सामग्री जोड़ रहे हैं।

यदि आप बड़े तारों को जोड़ रहे हैं तो यह स्मृति को बहुत जल्दी उपयोग करना शुरू कर देता है।

+0

विशेष रूप से प्रत्येक इंटरमीडिएट स्ट्रिंग 80,000 बाइट लेता है और LOH के लिए सही हो जाता है। –

1

यदि आप पढ़ रहे हैं, तो मुझे लगता है कि http://dotnetperls.com/stringbuilder-1 पर चर्चा वास्तव में उपयोगी है। गति और स्मृति उपयोग पर वास्तविक मीट्रिक के लिंक देखें।

इसके अलावा, "Shlemeil the Painter's Algorithm" की जोएल स्पॉल्स्की की चर्चा देखें। हालांकि वह सी के strcat फ़ंक्शन के बारे में बात कर रहा है, लेकिन सिद्धांत स्ट्रिंग पर सी # के प्लस ऑपरेटर पर लागू होता है। इसके अलावा, यह एक हंसी के लिए अच्छा है।

सामान्य रूप से, यदि आप परिशिष्ट संचालन तेजी से या कई बड़े तारों के साथ कर रहे हैं तो मैं स्ट्रिंगबिल्डर की सलाह देता हूं।

0

यह परिदृश्य पर भी निर्भर करता है। इसमें कोई संदेह नहीं है कि स्ट्रिंगबिल्डर ऑब्जेक्ट की तुलना में सामान्य सूची के साथ जोड़ना तेज़ है। लेकिन जेनेरिक सूची से डेटा पुनर्प्राप्ति के समय, यह स्ट्रिंगबिल्डर ऑब्जेक्ट की तुलना में बहुत धीमी होगी।

स्ट्रिंगबिल्डर _masterText का उपयोग करके जल्दी से वापस आ जाएगा।ToString() लेकिन जेनेरिक सूची के साथ, आपको पुनरावृत्ति का उपयोग करके मूल्य खींचना पड़ सकता है। और वह हो जाएगा महंगी प्रक्रिया जैसे: -

for (int x = 0; x < 100; x++) 
    { 
     Label3.Text += gen_list[x]; 
    } 

या आप के साथ की कोशिश कर सकते

Label3.Text = string.Join ("", gen_list.ToArray());

तो पुनर्प्राप्ति ऑपरेशन धीमा और महंगा होगा, और आप आसानी से सीपीयू स्पाइक देख सकते हैं।