3

私のプログラムは、ランダムアクセスで巨大なバイナリファイルからチャンクを読み取る必要があります。数千のエントリがある可能性のあるオフセットと長さのリストがあります。ユーザーがエントリを選択すると、プログラムはオフセットを探して長さバイトを読み取ります。

プログラムは内部でTMemoryStreamを使用して、ファイルから読み取られたチャンクを格納および処理します。データの読み取りは、次のようにTFileStreamを介して行われます。

FileStream.Position := Offset;
MemoryStream.CopyFrom(FileStream, Size);

これは正常に機能しますが、残念ながら、ファイルが大きくなるにつれて速度が低下します。ファイルサイズは数メガバイトから始まりますが、数十ギガバイトに達することがよくあります。読み取られるチャンクのサイズは約100キロバイトです。

ファイルの内容は私のプログラムによってのみ読み取られます。現時点でファイルにアクセスしているのはこのプログラムだけです。また、ファイルはローカルに保存されるため、これはネットワークの問題ではありません。

WindowsXPボックスでDelphi2007を使用しています。

このファイルアクセスを高速化するにはどうすればよいですか?

編集:

  • ファイルのどの部分が読み取られているかに関係なく、大きなファイルのファイルアクセスは低速です。
  • プログラムは通常、ファイルを順番に読み取りません。チャンクの順序はユーザー主導であり、予測することはできません。
  • 小さなファイルから同じように大きなチャンクを読み取るよりも、大きなファイルからチャンクを読み取る方が常に遅くなります。
  • 私は、ファイル全体を処理するのにかかる全体的な時間ではなく、ファイルからチャンクを読み取るためのパフォーマンスについて話しています。後者は明らかに大きなファイルの場合は時間がかかりますが、それはここでは問題ではありません。

皆さんに謝罪する必要があります。メモリマップトファイルを使用してファイルアクセスを実装した後、提案されたように、大きな違いはないことがわかりました。しかし、タイミングコードを追加した後、プログラムの速度を低下させるのはファイルアクセスではないことも判明しました。ファイルへのアクセスには、ファイルサイズに関係なく、実際にはほぼ一定の時間がかかります。ユーザーインターフェイスの一部(まだ特定していません)には、大量のデータでパフォーマンスの問題があるようで、最初にプロセスを実行したときに、どういうわけか違いを確認できませんでした。

ボトルネックを特定するのが面倒でごめんなさい。

4

3 に答える 3

3

CreateFile ()WinAPI関数のヘルプトピックを開くと、FILE_FLAG_NO_BUFFERINGやFILE_FLAG_RANDOM_ACCESSなどの興味深いフラグが表示されます。あなたは彼らと遊んでパフォーマンスを得ることができます。

次に、サイズが100Kbであっても、ファイルデータをコピーすることは、操作を遅くする余分な手順です。CreateFileMapping関数とMapViewOfFile関数を使用して、データへのすぐに使用できるポインターを取得することをお勧めします。このようにして、コピーを回避し、場合によっては特定のパフォーマンス上の利点を得ることができます(ただし、速度を注意深く測定する必要があります)。

于 2011-01-06T13:32:04.630 に答える
0

多分あなたはこのアプローチを取ることができます:

最大ファイル位置でエントリを並べ替えてから、次のように並べ替えます。

  1. ファイルの最初のXMBのみを必要とするエントリを取得します(特定のファイル位置まで)
  2. X MBをファイルからバッファ(TMemorystream
  3. 次に、バッファからエントリを読み取ります(マルチスレッドの場合もあります)
  4. すべてのエントリに対してこれを繰り返します。

つまり、ファイルの一部をキャッシュし、それに適合するすべてのエントリを読み取り(マルチスレッド)、次の部分をキャッシュします。

たぶん、元のアプローチをとるだけでスピードを上げることができますが、エントリを位置で並べ替えます。

于 2011-01-06T14:30:22.040 に答える
0

DelphiのストックTMemoryStreamは、メモリの割り当て方法が原因で低速です。NexusDBの会社には、はるかに効率的なTnxMemoryStreamがあります。よりうまく機能する無料のものがあるかもしれません。

標準のDelphiTFileStreamも、最も効率的なコンポーネントではありません。歴史のさかのぼ​​りJulianBucknallは、BufferedFileStreamという名前のコンポーネントを雑誌またはファイルストリームを非常に効率的に処理する場所で公開しました。

幸運を。

于 2011-01-08T01:09:59.857 に答える