3

1Kbから100kbまでのサイズの3000のcsvファイルを含むフォルダーがあります。これらのファイルのすべての行は43文字の長さです。合計サイズは171Mbです。

これらのファイルをできるだけ速く解析するプログラムを作成しようとしています。

私は最初に自分の実装を試しましたが、これらの結果に満足していませんでした。次に、StackOverflowでLumenWorks.Framework.IO.Csvを見つけました。それは大胆な主張をしています:

145のフィールドと50,000のレコードを含む45MBのCSVファイルを使用して、より現実的な数値を提供するために、リーダーは約30MB/秒を処理していました。全体として、1.5秒かかりました。マシンの仕様はP43.0GHz、1024MBでした。

私は単にそれらの結果の近くに何も得られません。私のプロセスは>>10分かかります。これは、1つの大きなストリームではなく、小さなファイルがたくさんあり、そこにオーバーヘッドがあるためですか?他に何かできることはありますか?

LumenWorksの実装は、引用符、エスケープ、コメント、複数行のフィールドを処理することは言うまでもなく、私自身の実装よりも速くはないと感じています(ベンチマークはしていません)。カンマ区切りの整数の非常に規則的な形式があります。

乾杯

4

4 に答える 4

4

CSVファイルの解析はI/Oバウンドであり、ディスクからデータを読み取る速度によって決まります。消費者レベルのハードドライブの場合、これまでで最速の速度は1秒あたり約50〜60MBです。このLumenWorksはその限界に近いように聞こえます。

この種のスループットは、 1つの大きなファイルを含むきれいで断片化されていないディスクでしか得られません。そのため、ディスクリーダーヘッドは、多くの移動を必要とせずに、トラック間の移動だけでデータをポンピングします。頭を動かすのは遅い部分で、通常は平均約16ミリ秒です。

3000個のファイルを読んでいるときは頭の動きがたくさんあります。ファイルを開くだけで約50ミリ秒かかります。ボトルネックを見つけるために、少なくとも同等のテストを実行してください。優れたテキストエディタを使用し、コピー/貼り付けして1つの巨大なファイルも作成します。最初にディスクデフラガーを実行します。デフラグラーはまともな無料のものです。

コードの改善に関しては、文字列に注意してください。それらは大量のガベージを生成し、CPUキャッシュの局所性が低くなる可能性があります。スレッドはI/Oバウンドコードを高速化することはできません。唯一可能な改善点は、ファイルを読み取る1つのスレッドと、読み取りと変換が重複するように変換を行う別のスレッドです。複数のスレッドが読み取りを行うのは無意味です。それらは順番にディスクを待機します。

そして、ファイルシステムのキャッシュに注意してください。同じファイルで2回目にテストを実行すると、ディスクではなくメモリからデータが取得されます。これは高速ですが、本番環境でどのように機能するかはわかりません。

于 2011-01-07T06:23:32.450 に答える
0

すべてのファイルが一度に「表示」されて処理されますか?それらがプログラムによって処理される1つのファイルに「到着」するので、それらを段階的にマージすることはできませんか?10分は+/-7MBのデータを処理するのに長い時間です(あなたが引用した数字からの最悪のシナリオ)?

于 2011-01-07T06:18:11.630 に答える
0

別のスレッドでファイルを読み込んでみてください。データを同期的に読み取る必要がある場合は、ファイルハンドルの開閉を処理するスレッドを作成し、キューを実装して実際に単一のスレッドでデータを解析することができます。

于 2011-01-07T06:18:30.547 に答える
0

LogParserを使用してみましたか?これ以上速くなるかどうかはわかりませんが、いくつかのシナリオで成功しました。簡単にテストする価値があるかもしれません。

ログパーサー2.2

あなたの例のようにたくさんの小さなCSVから読み取るほうが速いかもしれません。とにかく、ルーメンとlogparser(およびその他の提案)の両方と比較できるように、独自のコードをベンチマークする必要があります。仮定は悪いです。

于 2011-01-10T22:41:03.083 に答える