この問題を初めて経験したわけではありません。Javaアプリケーション(バニラデータ処理)パフォーマンスの最大化
私は、Java Mission ControlでFlight Recorderの記録を見て、Scala/Javaコードを最適化しています。一番ホットな方法、次にメモリ割り当てを見てみると、アプリケーションの実行速度は50倍、または3倍速くなります。
これまでのところ、CPU使用率は60〜90%で、メモリ使用量は最大4GBヒープのうち2GBです。しかし、私はより多くのスピードを追い出すことができると思う。
特性:
- シングルスレッド処理、ファイルシステムから1つのファイルを読み込みます。
- ファイルシステムの読み取り速度が1GB/sであるが、処理速度が5MB/s(分岐、ステートマシンなど)であるシーケンシャル読み取り。
- できる限りガベージコレクションを最小限に抑えました。
- 純粋なJVMコードのファンシーライブラリはありません。 1つのアプリケーションで
for line in file // using an iterator which would call into a file result = process_line(line) state = state.process(result) if state.emits: println(state.result)
私は、次の最もホットなメソッドを持っています::他には
scala.collection.immutable.HashMap$HashTrieMap.getO(Object, Int, Int) 6.75% java.io.BufferedInputStream.read() 4.97%
(これは私の上からである
コードは大体この(擬似コードで)のように見えますヘッド):
(some sort of garbage collection process) 9%
... 7%
これらを発する?私は試してみて、はるかに複雑なコードのパフォーマンスの向上はほとんど得られませんでした。
次はどこですか?
process_line()
を1つのスレッドで実行してから、コンテキスト切り替えを最小限に抑えるために別のスレッドでその状態を反復する必要がありますか?おそらくそれが物事を遅らせるものでしょうか?
これについて正しい方法は何ですか?私はまだ問題自体を並列化したくありません。
私は、CPUを使用して最も多くの時間を費やしている場所に集中し、最適化できるか、別のスレッドに作業を渡すことができるかどうかを確認します。私。あなたが正しい方向に向かっているなら、あなたは最適化し続ける必要があります。 –
もう少し詳しく説明するように質問を更新しました。 「最もホットな」方法はありません。異なるパッケージから、おおよそ同様の量のCPUを使用しています。 –
私はあなたが持っているようなソートされたコレクションの疑いがあり、あなたがそれなしでコードを書くことができるかどうかを見ます。 BufferedInputStream.read()は、一度にバイトをブロックすることを理想的に読み取るほど高価ではありませんが、なぜこれを行うかによって異なります。私はどのように多くのメソッドが "ノイズ"のespコレクション操作で、アプリケーションのコアロジックではないかを見ていきます。 –