0

1 GB のテキスト ファイルがあり、それを読みたいとします。このファイルを開こうとすると、「メモリ オーバーフロー」エラーが発生します。私が知っている、通常の答えは「StreamReader.ReadLine() メソッドを使用する」です。しかし、私はこれがどのように機能するのか疑問に思っています。ReadLine メソッドを使用するプログラムが行を取得したい場合、遅かれ早かれテキスト ファイル全体を開く必要があります。私の知る限り、ファイルはディスクに保存され、「オールオアナッシング」の原則でメモリ内で開くことができます。ReadLine() メソッドを使用して、1 GB のテキスト ファイルの 1 行のみを一度にメモリに格納する場合、1 GB のテキスト ファイルの読み取り中に、1 GB のテキスト ファイルのすべての行に対してディスク IO を実行する必要があります。これはパフォーマンスのために行うにはひどいことではありませんか?

私はとても混乱していて、これについていくつかの詳細が欲しいです.

4

3 に答える 3

5

これは、1 GB のテキスト ファイルのすべての行に対してディスク IO を実行する必要があることを意味します。

いいえ、ReadLine() 呼び出しと物理ディスクの間には多くのレイヤーがあり、これが問題にならないように設計されています。最も重要なもの:

  • StreamReader のジョブを実行する基になるクラスである FileStream は、バッファーを使用して ReadFile() 呼び出しの数を減らします。デフォルトのサイズは 4096 バイトです
  • ReadFile() は、ディスクではなく、ファイル システム キャッシュからファイル データを読み取ります。これにより、ディスク ドライバーが呼び出される場合がありますが、これはあまり一般的ではありません。オペレーティングシステムは、ファイルからより多くのデータを読み取る可能性が高いと推測するのに十分なほど賢く、それが安価であり、RAM が他の目的に使用されていない限り、ディスクから事前に読み取ります。通常、ディスク シリンダー全体に相当するデータを丸呑みします。
  • ディスクドライブ自体にもキャッシュがあり、通常は数メガバイトです。

ファイル システム キャッシュは、群を抜いて最も重要なものです。また、プログラムを正確にプロファイリングすることができなくなるため、注意が必要です。テストを何度も実行すると、プログラムは実際にはディスクから読み取ることはなく、キャッシュのみを読み取ります。これにより、非現実的な速さになります。1 GB のファイルが収まらない場合がありますが、マシンに搭載されている RAM の量によって異なります。

于 2013-01-18T22:57:00.327 に答える
1

通常、舞台裏でFileStreamオブジェクトが開かれ、ディスクからファイルの大きなブロックが読み取られ、メモリに取り込まれます。このブロックはcacheReadLine() が読み取るための として機能するため、各 ReadLine() がディスク アクセスを引き起こすことを心配する必要はありません。

于 2013-01-18T22:48:59.210 に答える
0

何のパフォーマンスにとってひどいことですか?

メモリ内のファイル全体を処理するために使用できるメモリがあることを考えると、明らかに高速になるはずです。

ただし、連続したブロックを見つけて割り当てるにはコストがかかります。

ギグは ram の重要なブロックです。プロセスにそれがある場合、何が問題になるのでしょうか?

スワッピングは、ストリーミングよりも簡単に害を及ぼす可能性があります。

一度にすべてのファイルが必要ですか、常に必要ですか?

あなたが読み書きに行った場合。それはあなたに何をしますか?

ファイルが 2 GB になったらどうしますか?

1 つの要因を最適化できます。その前に、それが正しいものであることを確認する必要があります。何よりも、これが実際のマシンであることを覚えておく必要があります。リソースには限りがあるため、最適化は常に Peter から Paul への支払いを奪います。ピーターは動揺するかもしれません...

于 2013-01-18T22:58:54.167 に答える