6

を使用して、多数のテキストファイルを1行ずつ処理していますBufferReader.readlLine()

同じサイズの2つのファイルは130MBですが、1つは処理に40秒かかり、もう1つは75秒かかります。

1つのファイルに180万行あり、他のファイルには210万行あることに気付きました。しかし、同じサイズの300万行のファイルを処理しようとすると、処理に30分かかりました。

だから私の質問は:

  1. これは、バッファリーダーのシーク時間によるものですか(ファイルがどのようにBufferedReader機能するか、またはファイルを1行ずつ解析するかを知りたいですか?)

  2. ファイルを1行ずつより速く読み取る方法はありますか?

友よ、私はもう少し詳細を提供しています。

正規表現を使用して行を3つの部分に分割し、次にSimpleUnsortedWriter(Cassandraが提供)を使用して、キー、列、および値としてファイルに書き込みます。16MBのデータが処理された後、ディスクにフラッシュされます。

ただし、処理ロジックはすべてのファイルで同じです。サイズが330MBのファイルが1つでも、30秒で処理される行数は約100万行になります。理由は何でしょうか?

deviceWriter = new SSTableSimpleUnsortedWriter(
        directory,
        keyspace,
        "Devices",
        UTF8Type.instance,
        null,
        16);

Pattern pattern = Pattern.compile("[\\[,\\]]");
while ((line = br.readLine()) != null)          
{
    //split the line i n row column and value
    long timestamp = System.currentTimeMillis() * 1000;
    deviceWriter .newRow(bytes(rowKey));
    deviceWriter .addColumn(bytes(colmName), bytes(value), timestamp);

}

変更されまし-Xmx256M to -Xmx 1024Mたが、とにかく役に立ちません。

更新: 私の観察によると、(物理メモリ内の)バッファに書き込んでいるので、いいえ。バッファへの書き込みの数が増えているため、新しい書き込みには時間がかかります。(これは私の推測です)

返信してください。

4

4 に答える 4

5

唯一のことBufferedReaderは、基になるものからデフォルトサイズの8KReaderの内部char[]バッファーに読み込まれることです。すべてのメソッドは、使い果たされるまでそのバッファーで機能します。使い果たされると、基になるから別の8K(またはその他)が読み取られReaderます。ある種のreadLine()取り組みです。

正しく使用しても、実行時間が1.8m回線での40秒から3m回線での30分に増加することはありBufferedReaderません。コードに何か問題があるはずです。それを見せてください。

もう1つの可能性は、JVMに十分なヒープメモリがなく、ヒープが99%いっぱいで、最終的にはOutOfMemoryErrorより大きな入力が得られるため、30分のほとんどをガベージコレクションに費やしていることです。処理した行で何をしていますか?それらはメモリに保持されていますか?-Xmx 1024Mコマンドラインオプションを指定してプログラムを実行すると、違いがありますか?

于 2011-08-24T17:11:56.167 に答える
1

これBufferedReaderはおそらくパフォーマンスの問題の根本ではありません。

引用した数値に基づくと、コードに2次の複雑さが含まれているように思われます。たとえば、読んだすべての行について、以前に読んだすべての行を再検討しています。ここで推測しているだけですが、問題の一般的な例は、リストデータ構造を使用し、新しい行が前の行と一致するかどうかを確認することです。

于 2011-08-24T17:29:31.657 に答える
1

BufferedReaderはシークせず、改行が見つかるまで文字をキャッシュし、その行を文字列として返し、各行の後にバッファを破棄(再利用)します。そのため、シークをサポートしていないストリームやその他のリーダーでも使用できます。

したがって、行数だけでは、読者レベルでそれほど大きな違いは生じないはずです。ただし、非常に長い行は非常に大きな文字列と大量のRAMの割り当てを作成する可能性がありますが、それはあなたの場合ではないようです(その場合、GC時間の超過などでOutOfMemory例外がスローされる可能性があります)。

私があなたのコードで見ることができることについては、あなたは何も悪いことをしていません。RAMではないように見えるので、ある種の制限に達していると思います。おそらく、Cassandra側の厳しい制限と関係がありますか?カサンドラに書いている部分をコメントアウトしてみましたか?問題を引き起こしているのがあなたの側なのかカサンドラ側なのかを確認するだけです。

于 2011-08-24T17:03:49.343 に答える
1

NIO Bufferedは、BufferReaderよりも最適化されているため、調べてください。

別のフォーラムからのコードスニペット。http://www.velocityreviews.com/forums/t719006-bufferedreader-vs-nio-buffer.html

FileChannel fc = new FileInputStream("File.txt").getChannel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
fc.read(buffer);

編集:このスレッドも調べてくださいJavaで大きなファイルを読む

于 2011-08-24T17:05:25.467 に答える