JavaOne 2014 SFのセッションでJMHを使った性能計測をしていた他、先日日記で紹介したJava Magazineでも記事になっています。
http://d.hatena.ne.jp/torutk/20141006/p1
そこで、実際に試してみました。
まず、JMHツールのホームページを参照します。
http://openjdk.java.net/projects/code-tools/jmh/
推奨する使用法が記載されているので、それに沿って進めます。
まず、インターネット接続環境でJDK 8およびmavenをインストール・セットアップしたマシンを用意します。
JMHはビルドプロジェクトをmavenで作成するので、まずは次を実行します。オプションはJMHホームページのまま実行してみます。理解したらいろいろ変えることとします。
~$ mkdir jmh_excer ~$ cd jmh_excer jmh_excer$ mvn archetype:generate \ -DinteractiveMode=false \ -DarchetypeGroupId=org.openjdk.jmh \ -DarchetypeArtifactId=jmh-java-benchmark-archetype \ -DgroupId=org.sample \ -DartifactId=test \ -Dversion=1.0 : jmh_excer$ ls test jmh_excer$
すると、testディレクトリができます。ディレクトリツリーは次のようになりました。
test +-- pom.xml +-- src +-- main +-- org +-- sample +-- MyBenchmark.java
どうやら、artifactIdで指定したトップレベルディレクトリとgroupIdで指定したパッケージ構造で生成されるようです。生成されたMyBenchmark.javaは次です(ファイル先頭コメント削除しています)。
package org.sample; import org.openjdk.jmh.annotations.Benchmark; public class MyBenchmark { @Benchmark public void testMethod() { // place your benchmarked code here } }
ビルドは次です。
~jmh_excer$ cd test test$ mvn clean install : test$
ビルドすると、targetディレクトリとその中にbenchmarks.jarが生成されます。(他にもいろいろmaven流のディレクトリ・ファイルが生成されています)
実行します。
test$ java -jar target/benchmarks.jar # VM invoker: C:\java\jdk1.8.0\jre\bin\java.exe # VM options: <none> # Warmup: 20 iterations, 1 s each # Measurement: 20 iterations, 1 s each # Timeout: 10 min per iteration # Threads: 1 thread, will synchronize iterations # Benchmark mode: Throughput, ops/time # Benchmark: org.sample.MyBenchmark.testMethod # Run progress: 0.00% complete, ETA 00:06:40 # Fork: 1 of 10 # Warmup Iteration 1: 1516121404.924 ops/s # Warmup Iteration 2: 1497277602.725 ops/s : Iteration 19: 1483167358.513 ops/s Iteration 20: 1458119813.650 ops/s Result: 1461902009.817 ±(99.9%) 8548155.688 ops/s [Average] Statistics: (min, avg, max) = (1301371929.415, 1461902009.817, 1516355326.822), stdev = 36193426.438 Confidence interval (99.9%): [1453353854.129, 1470450165.504] # Run complete. Total time: 00:08:03 Benchmark Mode Samples Score Error Units o.s.MyBenchmark.testMethod thrpt 200 1461902009.817 ± 8548155.688 ops/s test$
Warmupを20回実施してからメソッド実行を20回実施するサイクルを10回繰り返し実施します。
ここでWarmup、メソッド実行の1回とは、メソッドの呼び出しが1回を意味するのではなく、1秒間メソッドを呼び出し続けることを意味していると思われます。
プログラム実施後、結果を表示します。
結果のScoreは、秒間何回メソッドを実行したかを示していると思われます。
Errorは標準偏差(または分散?)かと思われます。
ベンチマーク対象は@Benchmarkアノテーションを付与したメソッドです。このアノテーションは同じクラスに複数定義することができ、それぞれのメソッド毎に結果が表示されます。
Warmup回数、メソッド実行回数、サイクル回数はコマンドラインオプション、またはクラスへのアノテーションで指定することができます。