テキストファイルを1行ずつ読み取る最も速い方法は何ですか? 質問する

テキストファイルを1行ずつ読み取る最も速い方法は何ですか? 質問する

テキスト ファイルを 1 行ずつ読み取りたいのですが、.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
}

ベストアンサー1

ファイルを 1 行ずつ読み取る最も速い方法を見つけるには、ベンチマークを行う必要があります。私は自分のコンピューターでいくつかの小さなテストを行いましたが、私の結果があなたの環境に当てはまるとは期待できません。

StreamReader.ReadLine の使用

これが基本的にあなたの方法です。何らかの理由で、バッファ サイズを可能な限り小さい値 (128) に設定しました。この値を大きくすると、一般にパフォーマンスが向上します。既定のサイズは 1,024 で、その他の適切な選択肢は 512 (Windows のセクター サイズ) または 4,096 (NTFS のクラスター サイズ) です。最適なバッファ サイズを決定するには、ベンチマークを実行する必要があります。バッファが大きいほど、小さいバッファよりも高速ではないにしても、少なくとも遅くはありません。

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.SequentialScan。繰り返しますが、ベンチマークを行うのが最善の方法です。

File.ReadLines の使用

これは、固定バッファ サイズ 1,024 を使用して実装されている点を除けば、独自のソリューションと非常によく似ています。StreamReader私のコンピュータでは、バッファ サイズが 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 KB のファイルでテスト済み)、かなり遅くなります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クリーンかつ効率的だからです。特別な共有オプションが必要な場合 (たとえば、 を使用する場合FileShare.ReadWrite)、独自のコードを使用できますが、バッファ サイズを増やす必要があります。

おすすめ記事