2013-04-24 4 views
6

मुझे टेक्स्ट फ़ाइल में हजारों गतिशील रूप से जेनरेट की गई पंक्तियां लिखनी होंगी। मेरे पास दो विकल्प हैं, जो कम संसाधनों का उपभोग करते हैं और दूसरे की तुलना में तेज़ हैं?कम संसाधनों का उपभोग करता है और तेज़ी से फ़ाइल करता है File.AppendText या File.WriteAllText स्ट्रिंगबिल्डर में पहले संग्रहित करता है?

ए StringBuilder और File.WriteAllText का उपयोग

StringBuilder sb = new StringBuilder(); 
foreach(Data dataItem in Datas) 
{ 
sb.AppendLine(String.Format("{0}, {1}-{2}",dataItem .Property1,dataItem .Property2,dataItem .Property3)); 
} 
File.WriteAllText("C:\\example.txt", sb.ToString(), new UTF8Encoding(false)); 

बी File.AppendText

using(StreamWriter sw = File.AppendText("C:\\example.txt")){ 
           foreach (Data dataItem in Datas) 
           { 
            sw.WriteLine(String.Format("{0}, {1}-{2}",dataItem .Property1,dataItem .Property2,dataItem .Property3)); 
           } 
          } 
+5

http://ericlippert.com/2012/12/17/performance-rant/ –

+0

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

+1

मुझे यकीन नहीं है कि गति आपकी मुख्य चिंता यहां होनी चाहिए। मेमोरी उपयोग स्पष्ट रूप से आपके निर्णय को ड्राइव करना चाहिए। यदि डेटा हमेशा छोटा होता है तो आप यह निर्धारित करने के लिए कुछ परीक्षण चला सकते हैं कि कौन सा तेज़ है। – juharr

उत्तर

14

आपका पहला संस्करण, जो सब कुछ StringBuilder में डालता है और फिर इसे लिखता है, सबसे अधिक स्मृति का उपभोग करेगा। यदि पाठ बहुत बड़ा है, तो आपके पास स्मृति से बाहर निकलने की क्षमता है। इसमें तेजी से होने की संभावना है, लेकिन यह धीमा भी हो सकता है।

दूसरा विकल्प बहुत कम स्मृति का उपयोग करेगा (मूल रूप से, केवल StreamWriter बफर), और बहुत अच्छा प्रदर्शन करेगा। मैं इस विकल्प की सिफारिश करता हूं। यह अच्छी तरह से प्रदर्शन करता है - संभवतः पहले विधि से बेहतर - और स्मृति से बाहर निकलने के लिए समान क्षमता नहीं है।

आप आउटपुट बफर के आकार को बढ़ाकर इसे बहुत तेज कर सकते हैं। बल्कि

File.AppendText("filename") 

से साथ स्ट्रीम बनाएं:

const int BufferSize = 65536; // 64 Kilobytes 
StreamWriter sw = new StreamWriter("filename", true, Encoding.UTF8, BufferSize); 

64K के एक बफर आकार डिफ़ॉल्ट 4K बफर आकार की तुलना में बेहतर प्रदर्शन देता है। आप बड़े जा सकते हैं, लेकिन मुझे पता चला है कि 64K से बड़ा न्यूनतम प्रदर्शन लाभ देता है, और कुछ सिस्टम पर वास्तव में प्रदर्शन कम हो सकता है।

+0

यह बफर आकार अनुमान लगाना मुश्किल है, क्योंकि मुझे कभी भी लाइनों और डेटा की मात्रा कभी नहीं पता है। मुझे लगता है कि 2k और 4k के बीच। मुझे आउटऑफमेमरी अपवाद का खतरा था अगर मैं मनमाने ढंग से मुझे जो चाहिए उसे तुलना में एक बफरसाइज नाबालिग चुनने का जोखिम होगा। –

+0

@ अल्बर्टोएलओन: नहीं, एक बहुत छोटा बफर आकार चुनने से आपको स्मृति अपवाद नहीं मिलेगा। यह सिर्फ एक अस्थायी बफर है कि 'स्ट्रीमवाइटर' प्रत्येक चरित्र के लिए विंडोज़ 'लिखित' फ़ंक्शन को कॉल करने से रोकने के लिए उपयोग करता है। यह डेटा बफर करता है और फिर इसे ब्लॉक में लिखता है। यदि आप बफर से बड़ा ब्लॉक लिखने का प्रयास करते हैं तो आपको कोई त्रुटि नहीं मिलेगी। –

+0

बढ़िया! तब मुझे लगता है कि आपका समाधान मेरा दूसरा अपमान सुधारता है, मुझे यह पसंद है। –

7

आप कम से कम एक अन्य विकल्प है का उपयोग करना, File.AppendAllLines()

का उपयोग कर
var data = from item in Datas 
      select string.Format("{0}, {1}-{2}", item.Property1, item.Property2, item.Property3); 

File.AppendAllLines("Filename", data, new UTF8Encoding(false)); 

यह सैद्धांतिक रूप से आपके पहले दृष्टिकोण की तुलना में कम स्मृति का उपयोग करेगा क्योंकि एक समय में केवल एक पंक्ति स्मृति में बफर किया जाएगा।

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

अपने दूसरे का उपयोग कर मतलब है कि मैं/हे गति, किसी भी अन्य कारणों बौना जाएगा ताकि आप स्मृति के उपयोग को कम करने के रूप में juharr ऊपर बताया गया है पर ध्यान देना चाहिए (और भी समय से पहले अनुकूलन के खतरों को देखते हुए!) दृष्टिकोण, या जो मैंने यहां रखा है।

+0

मुझे लगता है कि मुझे यह सबसे अच्छा लगता है। अच्छा उत्तर। –

+0

मुझे आश्चर्य हुआ क्योंकि लाइनों की कम संख्या। अधिक सुगम है। लेकिन var डेटा क्या है? तारों की एक सरणी है? –

+0

@ अल्बर्टोलेन: 'डेटा' एक 'आईनेमेरेबल ' है। उसमें की विधियों को समझने के लिए आपको LINQ पर पढ़ना होगा। –

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