2016-04-12 9 views
6

मैं ऐसे एप्लिकेशन से निपट रहा हूं जिसमें संभावित रूप से बड़ी टेक्स्ट फ़ाइलों (~ 3 + जीबी) की श्रृंखला से पाठ की पूरी पंक्ति को यादृच्छिक रूप से पढ़ना आवश्यक है।मैं एक फ़ाइल को कुशलता से कैसे अनुक्रमित कर सकता हूं?

रेखाएं एक अलग लंबाई का हो सकती हैं।

आदेश GC को कम करने और, मैं में प्रदान की जाती समाधान का उपयोग कर रहा अनावश्यक तार बनाने के लिए: Is there a better way to determine the number of lines in a large txt file(1-2 GB)? प्रत्येक नई लाइन का पता लगाने और एक पास इसलिए lineNo => position यानी के एक सूचकांक के उत्पादन में स्टोर नक्शे में:

// maps each line to it's corresponding fileStream.position in the file  
List<int> _lineNumberToFileStreamPositionMapping = new List<int>(); 
  1. जब एक new line वेतन वृद्धि lineCount का पता लगाने और जोड़ने पूरी फ़ाइल
  2. के माध्यम से जाने fileStream.Position_lineNumberToFileStreamPositionMapping
  3. को

हम तो के लिए इसी तरह एक API का उपयोग करें:

public void ReadLine(int lineNumber) 
{ 
    var getStreamPosition = _lineNumberToFileStreamPositionMapping[lineNumber]; 
    //... set the stream position, read the byte array, convert to string etc. 
} 

यह समाधान वर्तमान में एक अच्छा प्रदर्शन प्रदान कर रहा है लेकिन वहाँ दो चीजें हैं मुझे पसंद नहीं है:

  1. के बाद से मैं नहीं जानता फ़ाइल में लाइनों की कुल संख्या, मैं array को पूर्वस्थापित नहीं कर सकता इसलिए मुझे List<int> का उपयोग करना होगा जिसमें वास्तव में मुझे जो चाहिए उसे दोहराए जाने का आकार बदलने की संभावित अक्षमता है;
  2. मेमोरी उपयोग, इसलिए ~ 1 जीबी की पाठ फ़ाइल के लिए उदाहरण के रूप में ~ 5 मिलियन लाइनों के पाठ के साथ उदाहरण के लिए सूचकांक ~ 150 एमबी है, मैं वास्तव में जितना संभव हो उतना कम करना चाहता हूं।

किसी भी विचार की बहुत सराहना की जाती है।

+0

सूचकांक 150 जीबी क्यों है? 5 मिलियन टन कच्चे भंडारण के 20 एमबी से कम है, तो आपको वह मूल्य कहां मिल रहा है? – DavidG

+0

यही है कि प्रोफाइलर मुझे दिखा रहा है लेकिन फिर मैंने गहरा खोला नहीं है। इसके अलावा, 20 एमबी आदर्श परिदृश्य होगा हालांकि वास्तविकता में यह दोगुना हो सकता है कि 'सूची' – MaYaN

+0

के आकार बदलने वाले तर्क के कारण शायद आपको एक सादे पुरानी सरणी का उपयोग करना चाहिए। सुनिश्चित नहीं है कि 'सूची' आपको यहां कुछ भी उपयोगी बनाती है। एक बार सूची बनाने के बाद, इसे सरणी में परिवर्तित करें और सूची के रास्ते को फेंक दें। – DavidG

उत्तर

3
  1. क्षमता को मैन्युअल रूप से बढ़ाने के लिए List.Capacity का उपयोग करें, शायद हर 1000 लाइनें या तो।

  2. यदि आप स्मृति के लिए प्रदर्शन करना चाहते हैं, तो आप यह कर सकते हैं: प्रत्येक पंक्ति की स्थिति को संग्रहीत करने के बजाय, केवल 100 वीं (या कुछ) रेखा की स्थिति को स्टोर करें। फिर, कहें, लाइन 253 की आवश्यकता है, लाइन 200 की स्थिति पर जाएं और 53 लाइनों की गिनती करें।

+1

aaaah ... बहुत अच्छा! मुझे यह पसंद है कि यह कोशिश करेगा। tnx! – MaYaN

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

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