私のプログラムは、ランダムアクセスで巨大なバイナリファイルからチャンクを読み込む必要があります。私は数千のエントリを持つオフセットと長さのリストを持っています。ユーザはエントリを選択し、プログラムはオフセットを求めて、lengthバイトを読み込みます。Delphiで巨大なファイルを読み込む最速の方法は何ですか?
プログラムは内部的にTMemoryStreamを使用して、ファイルから読み込んだチャンクを保存して処理します。データの読み取りは、次のようにTFileStreamを介して行われます。これは正常に動作しますが、ファイルが大きくなるにつれて、残念ながら、それはますます遅くなり
FileStream.Position := Offset;
MemoryStream.CopyFrom(FileStream, Size);
。ファイルサイズは数メガバイトから始まりますが、頻繁に数十ギガバイトに達します。読み込まれるチャンクは、およそ100キロバイトです。
ファイルの内容は、自分のプログラムでのみ読み取られます。これは、その時点でファイルにアクセスしている唯一のプログラムです。また、ファイルはローカルに保存されるため、ネットワーク上の問題ではありません。
私はDelphi 2007をWindows XPのボックスで使用しています。
このファイルへのアクセスを高速化するにはどうすればよいですか?
編集:
- ファイルアクセスに関係なく、ファイルの一部を読まされているの、大きなファイルの遅いです。
- 通常、プログラムはファイルを順番に読み込みません。チャンクの順序はユーザー主導であり、予測することはできません。
- 小さなファイルから同じ大きさのチャンクを読み取るよりも、大きなファイルからチャンクを読み取るのは、常に遅くなります。
- 私は、ファイル全体を処理するのにかかる全体的な時間ではなく、ファイルからチャンクを読み取るためのパフォーマンスについて話しています。後者は大きなファイルの方が明らかに時間がかかりますが、ここで問題にはなりません。
私はみんなに謝罪する必要があります:それは違いの多くをしなかったことが判明示唆したように、私は、メモリマップドファイルを使用してファイルアクセスを実現した後。しかし、それはプログラムを遅くするファイルアクセスではないという、より多くのタイミングコードを追加した後にも判明しました。ファイルアクセスは、ファイルサイズに関係なく、ほぼ一定の時間がかかります。私がまだ特定していないユーザーインターフェイスの一部は、大量のデータでパフォーマンスに問題があるようですが、何とか最初にプロセスのタイミングをとったときに何らかの違いが見られませんでした。
ボトルネックを特定するのは申し訳ありません。
明らかなことはありません。これらのストリームクラスは、システムファイルI/O関数のまわりのラッパーです。あなたはどのようにランダムアクセスパターンのものを大幅に改善できますか? –
あなたは単一のシーク/リードがユーザにとって著しく遅いと言っていますか?あるいは、これらの操作の大規模な「バッチ」が遅いのでしょうか?ディスクからデータが来ている場合は、ファイルのサイズに関係なく、シークとリードの操作はほぼ同じになります。 7200 rpmディスクでは、5〜10 msの間であるべきです。 –
メモリの断片化の問題が考えられます。操作間でTMemoryStreamを解放していますか?アプリケーションの寿命の間、それを生かしておき、減速が消えるかどうか確認してください。 –