Java で -server オプションを付けたら4割近くも速くなったときのメモ。
動機
ログファイル中の XML をパースして XPath で抜き出す調査用のツールを使っていたのですが、本番機 / ステージング機と開発機で実行速度に大きな差がありました。本番機・ステージング機・開発機はハードウェアのスペックからしてまったく違うとはいえ、同じログファイルに対して実行したときの TAT が2倍以上違うとかもザラにあり、少し調べてみました。
開発機では Client VM が使われていた
開発機の OS が 32bit Windows のため、デフォルトで Client VM が使われていたのが原因でした。java コマンドに -server オプションを指定して Server VM で実行するようにしたところ、TAT が4割近くも短くなりました。ちょっとしたツールだしあまり変わらないだろうと思っていたのですが、全く変わるものなんですね。
大雑把な計測結果をメモしておきます。
# Client VM で実行 PS >1..10 | foreach { Measure-Command { java -client Hoge }} | measure -Average TotalMilliseconds Count : 10 Average : 32756.72687 Sum : Maximum : Minimum : Property : TotalMilliseconds # Server VM で実行 PS >1..10 | foreach { Measure-Command { java -server Hoge }} | measure -Average TotalMilliseconds Count : 10 Average : 24059.97238 Sum : Maximum : Minimum : Property : TotalMilliseconds
ユースケースを元にキャッシュ化
Server VM を使うことで相当に速くなったのですが、使っていたツールの使われ方には以下のような偏りがあったので、
XML のパースと XPath での抜き出しは初回のみ行い、以後はそのキャッシュに対して「ごく一部」を適用するようにしてみました。
# 事前にパースしてキャッシュしておき、それを使うようにする PS >1..10 | foreach { Measure-Command { java -client -Dcache=enable Hoge }} | measure -Average TotalMilliseconds Count : 10 Average : 2667.87865 Sum : Maximum : Minimum : Property : TotalMilliseconds
圧倒的に速いですね。桁が1つ減りました。ちなみに、キャッシュからの検索には PowerShell の Get-Content と Where-Object を使っているのですが、grep コマンドに置き換えたらミリ秒で終わるようになりました。本番機・ステージング機で grep コマンドが使えないのが残念ですが、Get-Content と Where-Object を使う版でも2, 3秒で終わるのでまあいいかな、というところです。