前回の投稿で、C++のgetline関数がテキストファイルの行をどれだけ速く実行できるかを尋ねました。答えは約2GB / sで、確かに1 GB / sを超えていました。これは、いくつかの最高のディスクドライブやネットワーク接続よりも低速です。ソフトウェアが行に「ただ」アクセスするだけでよいことはめったにないことを考慮に入れると、ディスクやネットワークにバインドされるのではなく、テキストファイルの処理がプロセッサにバインドされるシステムを簡単に構築できます。
Javaはどうですか?Javaでは、テキストファイルの行にアクセスする標準的な方法は、BufferedReaderを使用することです。システムコールを回避するために、多くのテキスト行を含む大きな文字列を作成してから、文字列の長さを記録するだけの非常に単純な処理関数を呼び出します…
StringReader fr = new StringReader(data);
BufferedReader bf = new BufferedReader(fr);
bf.lines().forEach(s -> parseLine(s));
// elsewhere:
public void parseLine(String s) {
volume += s.length();
}
その結果、このベンチマークでは、同じシステム上でJavaはC ++よりも少なくとも2倍遅くなります。
BufferedReader.lines: 0.5GB/s
これはJavaが実行できる最善の方法ではありません。Javaはデータをはるかに高速に取り込むことができます。ただし、私の結果は、最近のシステムでは、Javaファイルの解析は、システムにバインドされているのではなく、プロセッサにバインドされていることが多いことを示しています。つまり、はるかに優れたディスクとネットワークカードを購入でき、システムがこれ以上速くなることはありません。もちろん、本当に優秀なJavaエンジニアがいない限り。
多くの企業は、おそらく問題に対してより多くのハードウェアを投入するだけです。
**更新:**以前のバージョンのコードには、1つの巨大な行を作成する小さなタイプミスがありました。これは、結果にあまり影響を与えないことがわかりました。一部の人々は、より技術的な詳細を求めました。ベンチマークは、GNU GCC8.1をC ++コンパイラとして使用し、Java12をすべてLinuxで使用してSkylakeプロセッサで実行しました。結果は、正確な構成によって異なります。
英語原稿:https://lemire.me/blog/2019/07/26/how-fast-can-a-bufferedreader-read-lines-in-java/