c# একটি টেক্সট ফাইল লাইন-দ্বারা-লাইন পড়তে দ্রুততম উপায় কি?




.net performance (7)

আমি লাইন দ্বারা একটি টেক্সট ফাইল লাইন পড়তে চান। আমি জানতে চাই যে আমি .NET C # বিষয়বস্তুর মধ্যে যতটা সম্ভব দক্ষতার সাথে এটি করছি।

এটাই আমি এখন পর্যন্ত চেষ্টা করছি:

var filestream = new System.IO.FileStream(textFilePath,
                                          System.IO.FileMode.Open,
                                          System.IO.FileAccess.Read,
                                          System.IO.FileShare.ReadWrite);
var file = new System.IO.StreamReader(filestream, System.Text.Encoding.UTF8, true, 128);

while ((lineOfText = file.ReadLine()) != null)
{
    //Do something with the lineOfText
}

File.ReadAllLines() একটি ফাইল পড়ার সবচেয়ে সরল উপায়গুলির মধ্যে একটি, এটি ধীরে ধীরে এক।

যদি আপনি খুব বেশি না করেই একটি ফাইলে লাইন পড়তে চান তবে এই বেঞ্চমার্ক অনুসারে , ফাইলটি পড়ার দ্রুততম উপায় হল এর পুরানো পদ্ধতি:

using (StreamReader sr = File.OpenText(fileName))
{
        string s = String.Empty;
        while ((s = sr.ReadLine()) != null)
        {
               //do minimal amount of work here
        }
}

যাইহোক, যদি আপনাকে প্রতিটি লাইন দিয়ে অনেক কিছু করতে হয় তবে এই নিবন্ধটি উপসংহারে পৌঁছেছে যে সর্বোত্তম উপায় হল নিম্নলিখিতটি (এবং যদি আপনি জানেন যে আপনি কতগুলি লাইন পড়তে যাচ্ছেন তবে এটি স্ট্রিং-এর বরাদ্দ করা দ্রুততর]:

AllLines = new string[MAX]; //only allocate memory here

using (StreamReader sr = File.OpenText(fileName))
{
        int x = 0;
        while (!sr.EndOfStream)
        {
               AllLines[x] = sr.ReadLine();
               x += 1;
        }
} //Finished. Close the file

//Now parallel process each line in the file
Parallel.For(0, AllLines.Length, x =>
{
    DoYourStuff(AllLines[x]); //do your work here
});

যদি আপনি .NET 4 ব্যবহার করেন তবে কেবল File.ReadLines ব্যবহার File.ReadLines যা এটি আপনার জন্য করে। আমি সন্দেহ করি এটি আপনার মতই অনেক বেশি , এটি ছাড়াও এটি FileOptions এবং একটি বৃহত্তর বাফার ব্যবহার করতে পারে (128 টি খুব ছোট মনে হয়)।


ফাইলের আকার বড় না হলে, সমস্ত ফাইল পড়তে দ্রুততর হয় তারপর স্ট্রিং বিভক্ত করুন:

var filestreams = sr.ReadToEnd().Split(Environment.NewLine, 
                              StringSplitOptions.RemoveEmptyEntries);

লাইন দ্বারা একটি ফাইল লাইন পড়ার দ্রুততম উপায় খুঁজে পেতে আপনাকে কিছু বেঞ্চমার্কিং করতে হবে। আমি আমার কম্পিউটারে কিছু ছোট পরীক্ষা করেছি কিন্তু আপনি আমার পরিবেশগুলিতে আমার ফলাফলগুলি প্রয়োগ করার আশা করছেন না।

StreamReader.ReadLine ব্যবহার করে

এটি মূলত আপনার পদ্ধতি। কিছু কারণে আপনি বাফারের আকারকে ক্ষুদ্রতম সম্ভাব্য মান (128) এ সেট করুন। বৃদ্ধি এই কর্মক্ষমতা বৃদ্ধি হবে। ডিফল্ট আকার 1,024 এবং অন্যান্য ভাল পছন্দগুলি 512 (উইন্ডোজের সেক্টর আকার) বা 4,096 (এনটিএফএস-তে ক্লাস্টার আকার)। আপনি একটি অনুকূল বাফার আকার নির্ধারণ করতে একটি বেঞ্চমার্ক চালানো হবে। একটি বড় বাফার - যদি দ্রুত না হয় - অন্তত একটি ছোট বাফারের চেয়ে কম নয়।

const Int32 BufferSize = 128;
using (var fileStream = File.OpenRead(fileName))
  using (var streamReader = new StreamReader(fileStream, Encoding.UTF8, true, BufferSize)) {
    String line;
    while ((line = streamReader.ReadLine()) != null)
      // Process line
  }

FileStream কনস্ট্রাক্টর আপনাকে FileOptions উল্লেখ করতে দেয়। উদাহরণস্বরূপ, যদি আপনি শুরু থেকে শেষ পর্যন্ত FileOptions.SequentialScan একটি বড় ফাইল পড়ছেন, তবে আপনি FileOptions.SequentialScan থেকে উপকৃত হতে FileOptions.SequentialScan । আবার, বেঞ্চমার্কিং আপনি করতে পারেন সেরা জিনিস।

ফাইল ব্যবহার করুন। ReadLines

এটি আপনার নিজের সমাধানের মতই অনেক বেশি, এটি StreamReader ব্যবহার করে প্রয়োগ করা হয়েছে যা একটি নির্দিষ্ট বাফার আকারের সাথে 1,024। আমার কম্পিউটারে 128 এর বাফার আকারের সাথে আপনার কোডের তুলনায় এটি আরও ভাল কার্য সম্পাদন করে। তবে, আপনি একটি বৃহত্তর বাফার আকার ব্যবহার করে একই কর্মক্ষমতা বৃদ্ধি পেতে পারেন। এই পদ্ধতিটি একটি ইটারার ব্লক ব্যবহার করে প্রয়োগ করা হয় এবং সমস্ত লাইনের জন্য মেমরি গ্রাস করে না।

var lines = File.ReadLines(fileName);
foreach (var line in lines)
  // Process line

File.ReadAllLines ব্যবহার করে

এটি পূর্বের পদ্ধতির মতই অনেক বেশি যা এই পদ্ধতিটি লাইনগুলির ফেরত অ্যারে তৈরি করতে ব্যবহৃত স্ট্রিংগুলির একটি তালিকা বৃদ্ধি করে যাতে মেমরির প্রয়োজনীয়তাগুলি বেশি হয়। যাইহোক, এটি String[] এবং একটি IEnumerable<String> যা আপনাকে এলোমেলোভাবে লাইনগুলি অ্যাক্সেস করার অনুমতি দেয়।

var lines = File.ReadAllLines(fileName);
for (var i = 0; i < lines.Length; i += 1) {
  var line = lines[i];
  // Process line
}

String.Split ব্যবহার করে

এই পদ্ধতিটি বেশ ধীর, কমপক্ষে বড় ফাইলগুলিতে (511 কেবি ফাইলটিতে পরীক্ষা করা হয়েছে), সম্ভবত String.Split কিভাবে String.Split হয় তার কারণে। এটি আপনার সমাধানগুলির তুলনায় প্রয়োজনীয় মেমরি বাড়ানোর জন্য সমস্ত লাইনের জন্য একটি অ্যারে বরাদ্দ করে।

using (var streamReader = File.OpenText(fileName)) {
  var lines = streamReader.ReadToEnd().Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
  foreach (var line in lines)
    // Process line
}

আমার পরামর্শ File.ReadLines ব্যবহার করা File.ReadLines কারণ এটি পরিষ্কার এবং দক্ষ। আপনি যদি বিশেষ ভাগ করার বিকল্পগুলির প্রয়োজন (উদাহরণস্বরূপ আপনি FileShare.ReadWrite ব্যবহার FileShare.ReadWrite ), আপনি নিজের কোডটি ব্যবহার করতে পারেন তবে আপনাকে বাফার আকার বাড়াতে হবে।


স্ট্যাক ওভারফ্লো প্রশ্নে এটি সম্পর্কে একটি ভাল বিষয় আছে 'পুরানো স্কুল' ফিরতি চেয়ে 'ফলন ফেরত' ধীর?

এটা বলে:

ReadAllLines মেমরির মধ্যে সমস্ত লাইন লোড এবং একটি স্ট্রিং []। ফাইলটি ছোট হলে সব ভাল এবং ভাল। যদি মেমরিতে ফাইলটি বড় হবে তবে ফাইলটি মেমরির বাইরে চলে যাবে।

অন্যদিকে, ReadLines, এক সময়ে এক লাইন ফেরত পেতে ফলন রিটার্ন ব্যবহার করে। এর সাথে, আপনি কোন আকার ফাইল পড়তে পারেন। এটা মেমরি মধ্যে পুরো ফাইল লোড না।

বলুন যে আপনি "foo" শব্দটি ধারণকারী প্রথম লাইন খুঁজে বের করতে চান এবং তারপর প্রস্থান করুন। ReadAllLines ব্যবহার করে, আপনাকে সম্পূর্ণ ফাইলটি মেমরিতে পড়তে হবে, এমনকি যদি প্রথম লাইনটিতে "foo" ঘটে। ReadLines দিয়ে, আপনি শুধুমাত্র একটি লাইন পড়তে। কোনটি দ্রুত হবে?


যদি আপনার পর্যাপ্ত মেমরি থাকে তবে আমি পুরো ফাইলটি মেমরি স্ট্রীমে পড়তে কিছু পারফরম্যান্স লাভ পেয়েছি এবং তারপরে লাইনগুলি পড়ার জন্য একটি স্ট্রিম পাঠক খোলার চেষ্টা করেছি। যেহেতু আপনি আসলেই সম্পূর্ণ ফাইলটি পড়ার পরিকল্পনা করছেন, তাই এটি কিছু উন্নতির ফল পেতে পারে।


নিম্নলিখিত কোড ব্যবহার করুন:

foreach (string line in File.ReadAllLines(fileName))

এই কর্মক্ষমতা পড়া একটি বিশাল পার্থক্য ছিল।

এটা মেমরি খরচ খরচ আসে, কিন্তু সম্পূর্ণ মূল্য!





text-files