Java で -server オプションを付けたら4割近くも速くなったメモ

Java で -server オプションを付けたら4割近くも速くなったときのメモ。

動機

ログファイル中の XML をパースして XPath で抜き出す調査用のツールを使っていたのですが、本番機 / ステージング機と開発機で実行速度に大きな差がありました。本番機・ステージング機・開発機はハードウェアのスペックからしてまったく違うとはいえ、同じログファイルに対して実行したときの TAT が2倍以上違うとかもザラにあり、少し調べてみました。

環境

  • 本番機・ステージング機: 64bit Windows
  • 開発機: 32bit Windows

開発機では 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 の大部分は毎回同じ
  • 毎回変わるのはごく一部だけ
  • 同じログファイルに対して「ごく一部」を変えながら何回も実行する

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秒で終わるのでまあいいかな、というところです。

まとめ

  • ほとんどの場合、Server VM を使っておけば OK *1
  • 32bit Windows なくなってほしい

*1:GUI でも Server VM を使いたいことのほうが多そう