ファイルを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はを。たとえば、大きなファイルを最初から最後まで順番に読み取る場合は、を利用すると便利ですFileOptions.SequentialScan
。繰り返しになりますが、ベンチマークはあなたができる最高のことです。
File.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の使用
おそらくString.Split
実装方法が原因で、少なくとも大きなファイル(511 KBのファイルでテスト済み)では、この方法はかなり遅くなります。また、すべての行に配列を割り当て、ソリューションと比較して必要なメモリを増やします。
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
)、独自のコードを使用できますが、バッファーサイズを増やす必要があります。
Fastest
、あなたのパフォーマンスや開発の視点から意味ですか?