1

現在、〜200万レコードのcsvファイルを解析するパーサーのセットアップがあります。次に、いくつかのフィルタリング アルゴリズムを適用して、含めたい/除外したいレコードを除外します。最後に、すべてを新しい csv ファイルに書き戻します。

いくつかのベンチマークを行ったところ、csv へのデータの書き込みは非常にコストがかかり、フィルター処理とファイルへの追加を同時に行うと、大幅な速度低下が発生することがわかりました。すべてのフィルタリングを実行して、書き込まれる行をキューに配置し、そのキューがいっぱいになるか、すべてのフィルタリングが完了したときに、2 番目のプロセスがすべての書き込みを独自に実行できるかどうか疑問に思っていました。

基本的に要約すると:

Read line 
Decide whether to discard or keep
if I'm keeping the file, add it to the "Write Queue"
Check if the write queue is full, if so, start the new process that will begin writing
Continue filtering until completed

ご助力いただきありがとうございます!

編集: 私が書いている方法は次のとおりです:

FileWriter fw = new FileWriter("myFile.csv");
BufferedWriter bw = new BufferedWriter(fw);
while(read file...) {
   //perform filters etc...
    try {
        bw.write(data.trim());
        bw.newLine();

    }catch(IOException e) {
        System.out.println(e.getMessage());
    }
4

2 に答える 2

3

読み取りプロセスと書き込みプロセスは両方とも I/O バウンド (ディスク上のセクターへのシークとメモリとの間のディスク I/O の実行) ですが、フィルタリング プロセスは完全に CPU バウンドです。これは、マルチスレッドの良い候補です。

読み取り、フィルタリング、書き込みの 3 つのスレッドを使用します。これは 2 つのキューを呼び出しますが、処理する前にキューがいっぱいになるのを待つ理由はありません。

  • リーダー スレッドはファイルから読み取り、受信キューに行を追加します。
  • フィルター スレッドは受信キューから行を取得し、フィルターを通過した行を送信キューに書き込みます。
  • ライター スレッドは、発信キューから行を取得し、新しいファイルに書き込みます。

リーダー スレッドとライター スレッド間の競合を最小限に抑えるために、バッファー付きのリーダーとライターを必ず使用してください。フィルタリング プロセスがかなり単純であると仮定すると、ディスク シークがボトルネックになるため、ディスク シークを最小限に抑える必要があります。

于 2012-07-17T03:51:15.533 に答える
0

Springの使用に制約がない限り、SpringBatchの使用を検討することをお勧めします。

于 2012-07-17T04:23:17.917 に答える