JMHを使用した計測を行った場合、通常は計測結果はコンソールに出力されますが、
オプションの指定で計測結果をファイルに出力することができます。
また、出力する形式(CSV, JSON, ...)を指定することも可能です。
ファイル名指定で計測結果のレポートを出力する
OptionsBuilder#result
で 計測結果を出力するファイルのファイル名を指定すると、ベンチマーク取得後に結果がそのガファイルに出力されます。
(その他のサンプルでも同様ですが、Eclipseで実行した場合は対象プロジェクトのTOPディレクトリ直下に結果のファイルが出力されます)
■サンプルコード
結果を出力するファイル名に"jmh-report.txt"を指定しています。
import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Fork; import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Warmup; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; @Warmup(iterations=3) @Measurement(iterations=8) @OutputTimeUnit(TimeUnit.MILLISECONDS) @BenchmarkMode(Mode.Throughput) @Fork(1) public class ResultToFileBenchmark { @Benchmark public void date() { java.util.Date d = new java.util.Date(); } @Benchmark public void calndar() { java.util.Calendar c = java.util.Calendar.getInstance(); } public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .result("jmh-report.txt") .include(ResultToFileBenchmark.class.getName()) .build(); new Runner(opt).run(); } }
■実行結果(コンソールへの出力内容)
(一部省略)
# Warmup: 3 iterations, 1 s each # Measurement: 8 iterations, 1 s each # Timeout: 10 min per iteration # Threads: 1 thread, will synchronize iterations # Benchmark mode: Throughput, ops/time # Benchmark: org.jmh.sample.resultformat.ResultToFileBenchmark.calndar # Run progress: 0.00% complete, ETA 00:00:22 # Fork: 1 of 1 # Warmup Iteration 1: 860.543 ops/ms # Warmup Iteration 2: 1750.526 ops/ms # Warmup Iteration 3: 2037.289 ops/ms Iteration 1: 2248.850 ops/ms Iteration 2: 2235.143 ops/ms Iteration 3: 2254.577 ops/ms Iteration 4: 2232.210 ops/ms Iteration 5: 2240.256 ops/ms Iteration 6: 2215.086 ops/ms Iteration 7: 2223.034 ops/ms Iteration 8: 2239.323 ops/ms Result "calndar": 2236.060 ±(99.9%) 24.613 ops/ms [Average] (min, avg, max) = (2215.086, 2236.060, 2254.577), stdev = 12.873 CI (99.9%): [2211.447, 2260.673] (assumes normal distribution) # Warmup: 3 iterations, 1 s each # Measurement: 8 iterations, 1 s each # Timeout: 10 min per iteration # Threads: 1 thread, will synchronize iterations # Benchmark mode: Throughput, ops/time # Benchmark: org.jmh.sample.resultformat.ResultToFileBenchmark.date # Run progress: 50.00% complete, ETA 00:00:12 # Fork: 1 of 1 # Warmup Iteration 1: 36258.596 ops/ms # Warmup Iteration 2: 39107.596 ops/ms # Warmup Iteration 3: 43195.965 ops/ms Iteration 1: 43738.107 ops/ms Iteration 2: 43637.666 ops/ms Iteration 3: 43731.485 ops/ms Iteration 4: 43573.084 ops/ms Iteration 5: 42717.360 ops/ms Iteration 6: 43211.566 ops/ms Iteration 7: 42826.822 ops/ms Iteration 8: 42844.488 ops/ms Result "date": 43285.072 ±(99.9%) 837.663 ops/ms [Average] (min, avg, max) = (42717.360, 43285.072, 43738.107), stdev = 438.114 CI (99.9%): [42447.409, 44122.735] (assumes normal distribution) # Run complete. Total time: 00:00:24 Benchmark Mode Cnt Score Error Units ResultToFileBenchmark.calndar thrpt 8 2236.060 ± 24.613 ops/ms ResultToFileBenchmark.date thrpt 8 43285.072 ± 837.663 ops/ms Benchmark result is saved to jmh-report.txt
■ファイルへの出力内容
ファイル(jmh-report.txt)には以下の内容が出力されます
"Benchmark","Mode","Threads","Samples","Score","Score Error (99.9%)","Unit" "org.jmh.sample.resultformat.ResultToFileBenchmark.calndar","thrpt",1,8,2236.060013,24.612811,"ops/ms" "org.jmh.sample.resultformat.ResultToFileBenchmark.date","thrpt",1,8,43285.072457,837.663008,"ops/ms"
ResultFormatType.CSV
- CSV形式で結果を出力する
OptionsBuilder#resultFormat
を使用することで計測結果の出力形式を指定するとが可能です。
また、形式を指定するとOptionsBuilder#resultFormat
を実行しなくても拡張子まで含めてファイル名を自動的に決定してくれます。
CSV形式の場合ファイル名は、"jmh-result.csv" になります。
■サンプルコード
CSV形式で出力するためにOptionsBuilder#resultFormat
でResultFormatType.CSV
を指定しています。
import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Fork; import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Warmup; import org.openjdk.jmh.results.format.ResultFormatType; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; @Warmup(iterations=3) @Measurement(iterations=8) @OutputTimeUnit(TimeUnit.MILLISECONDS) @BenchmarkMode(Mode.Throughput) @Fork(1) public class CSVFormatBenchmark { @Benchmark public void date() { java.util.Date d = new java.util.Date(); } @Benchmark public void calndar() { java.util.Calendar c = java.util.Calendar.getInstance(); } public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .resultFormat(ResultFormatType.CSV) .include(CSVFormatBenchmark.class.getName()) .build(); new Runner(opt).run(); } }
■実行結果(コンソールへの出力内容)
(一部省略)
# Warmup: 3 iterations, 1 s each # Measurement: 8 iterations, 1 s each # Timeout: 10 min per iteration # Threads: 1 thread, will synchronize iterations # Benchmark mode: Throughput, ops/time # Benchmark: org.jmh.sample.resultformat.CSVFormatBenchmark.calndar # Run progress: 0.00% complete, ETA 00:00:22 # Fork: 1 of 1 # Warmup Iteration 1: 801.988 ops/ms # Warmup Iteration 2: 1717.748 ops/ms # Warmup Iteration 3: 2063.707 ops/ms Iteration 1: 2228.389 ops/ms Iteration 2: 2220.809 ops/ms Iteration 3: 2153.975 ops/ms Iteration 4: 2127.324 ops/ms Iteration 5: 2140.863 ops/ms Iteration 6: 2149.958 ops/ms Iteration 7: 2199.567 ops/ms Iteration 8: 1941.240 ops/ms Result "calndar": 2145.266 ±(99.9%) 173.484 ops/ms [Average] (min, avg, max) = (1941.240, 2145.266, 2228.389), stdev = 90.736 CI (99.9%): [1971.782, 2318.750] (assumes normal distribution) # Warmup: 3 iterations, 1 s each # Measurement: 8 iterations, 1 s each # Timeout: 10 min per iteration # Threads: 1 thread, will synchronize iterations # Benchmark mode: Throughput, ops/time # Benchmark: org.jmh.sample.resultformat.CSVFormatBenchmark.date # Run progress: 50.00% complete, ETA 00:00:12 # Fork: 1 of 1 # Warmup Iteration 1: 37353.221 ops/ms # Warmup Iteration 2: 37525.984 ops/ms # Warmup Iteration 3: 41822.555 ops/ms Iteration 1: 42684.230 ops/ms Iteration 2: 43107.547 ops/ms Iteration 3: 43209.845 ops/ms Iteration 4: 42733.811 ops/ms Iteration 5: 43333.149 ops/ms Iteration 6: 40338.558 ops/ms Iteration 7: 38625.473 ops/ms Iteration 8: 39366.701 ops/ms Result "date": 41674.914 ±(99.9%) 3664.312 ops/ms [Average] (min, avg, max) = (38625.473, 41674.914, 43333.149), stdev = 1916.506 CI (99.9%): [38010.603, 45339.226] (assumes normal distribution) # Run complete. Total time: 00:00:24 Benchmark Mode Cnt Score Error Units CSVFormatBenchmark.calndar thrpt 8 2145.266 ± 173.484 ops/ms CSVFormatBenchmark.date thrpt 8 41674.914 ± 3664.312 ops/ms Benchmark result is saved to jmh-result.csv
■ファイルへの出力内容
ファイル(jmh-result.csv)には以下の通りCSV形式で出力されます。
(ただ、デフォルトの場合もカンマ区切りのCSV形式で出力されていたので違いが無いですが・・・)
"Benchmark","Mode","Threads","Samples","Score","Score Error (99.9%)","Unit" "org.jmh.sample.resultformat.CSVFormatBenchmark.calndar","thrpt",1,8,2145.265649,173.484068,"ops/ms" "org.jmh.sample.resultformat.CSVFormatBenchmark.date","thrpt",1,8,41674.914382,3664.311779,"ops/ms"
ResultFormatType.TEXT
- スペース区切りで結果を出力する
以下、OptionsBuilder#resultFormat
にResultFormatType.TEXT
を指定した場合のサンプルです。
ファイル名は、"jmh-result.text" になります。
■サンプルコード
OptionsBuilder#resultFormat
でResultFormatType.TEXT
を指定しています。
import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Fork; import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Warmup; import org.openjdk.jmh.results.format.ResultFormatType; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; @Warmup(iterations=3) @Measurement(iterations=8) @OutputTimeUnit(TimeUnit.MILLISECONDS) @BenchmarkMode(Mode.Throughput) @Fork(1) public class TextFormatBenchmark { @Benchmark public void date() { java.util.Date d = new java.util.Date(); } @Benchmark public void calndar() { java.util.Calendar c = java.util.Calendar.getInstance(); } public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .resultFormat(ResultFormatType.TEXT) .include(TextFormatBenchmark.class.getName()) .build(); new Runner(opt).run(); } }
■実行結果(コンソールへの出力内容)
(一部省略)
# Warmup: 3 iterations, 1 s each # Measurement: 8 iterations, 1 s each # Timeout: 10 min per iteration # Threads: 1 thread, will synchronize iterations # Benchmark mode: Throughput, ops/time # Benchmark: org.jmh.sample.resultformat.TextFormatBenchmark.calndar # Run progress: 0.00% complete, ETA 00:00:22 # Fork: 1 of 1 # Warmup Iteration 1: 840.722 ops/ms # Warmup Iteration 2: 1811.098 ops/ms # Warmup Iteration 3: 1994.031 ops/ms Iteration 1: 2163.944 ops/ms Iteration 2: 2059.981 ops/ms Iteration 3: 2175.931 ops/ms Iteration 4: 2139.949 ops/ms Iteration 5: 2257.767 ops/ms Iteration 6: 2193.703 ops/ms Iteration 7: 2190.150 ops/ms Iteration 8: 2009.930 ops/ms Result "calndar": 2148.919 ±(99.9%) 151.271 ops/ms [Average] (min, avg, max) = (2009.930, 2148.919, 2257.767), stdev = 79.118 CI (99.9%): [1997.649, 2300.190] (assumes normal distribution) # Warmup: 3 iterations, 1 s each # Measurement: 8 iterations, 1 s each # Timeout: 10 min per iteration # Threads: 1 thread, will synchronize iterations # Benchmark mode: Throughput, ops/time # Benchmark: org.jmh.sample.resultformat.TextFormatBenchmark.date # Run progress: 50.00% complete, ETA 00:00:12 # Fork: 1 of 1 # Warmup Iteration 1: 30056.156 ops/ms # Warmup Iteration 2: 30540.027 ops/ms # Warmup Iteration 3: 43359.686 ops/ms Iteration 1: 43069.238 ops/ms Iteration 2: 42919.146 ops/ms Iteration 3: 34731.576 ops/ms Iteration 4: 38545.223 ops/ms Iteration 5: 42328.447 ops/ms Iteration 6: 37412.075 ops/ms Iteration 7: 37396.214 ops/ms Iteration 8: 38859.252 ops/ms Result "date": 39407.646 ±(99.9%) 5835.543 ops/ms [Average] (min, avg, max) = (34731.576, 39407.646, 43069.238), stdev = 3052.102 CI (99.9%): [33572.104, 45243.189] (assumes normal distribution) # Run complete. Total time: 00:00:24 Benchmark Mode Cnt Score Error Units TextFormatBenchmark.calndar thrpt 8 2148.919 ± 151.271 ops/ms TextFormatBenchmark.date thrpt 8 39407.646 ± 5835.543 ops/ms Benchmark result is saved to jmh-result.text
■ファイルへの出力内容
ファイル(jmh-result.text)には以下の通りスペース区切りで各項目が出力されます。
Benchmark Mode Cnt Score Error Units TextFormatBenchmark.calndar thrpt 8 2148.919 ± 151.271 ops/ms TextFormatBenchmark.date thrpt 8 39407.646 ± 5835.543 ops/ms
ResultFormatType.JSON
- JSON形式で結果を出力する
JSON形式で出力する場合は、OptionsBuilder#resultFormat
の引数にResultFormatType.JSON
を指定します。
JSON形式の場合ファイル名は、"jmh-result.json" になります。
■サンプルコード
JSON形式で出力するためにOptionsBuilder#resultFormat
でResultFormatType.JSON
を指定しています。
import java.util.concurrent.TimeUnit; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Fork; import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.OutputTimeUnit; import org.openjdk.jmh.annotations.Warmup; import org.openjdk.jmh.results.format.ResultFormatType; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; @Warmup(iterations=3) @Measurement(iterations=8) @OutputTimeUnit(TimeUnit.MILLISECONDS) @BenchmarkMode(Mode.Throughput) @Fork(1) public class JSONFormatBenchmark { @Benchmark public void date() { java.util.Date d = new java.util.Date(); } @Benchmark public void calndar() { java.util.Calendar c = java.util.Calendar.getInstance(); } public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .resultFormat(ResultFormatType.JSON) .include(JSONFormatBenchmark.class.getName()) .build(); new Runner(opt).run(); } }
■実行結果(コンソールへの出力内容)
(一部省略)
# Warmup: 3 iterations, 1 s each # Measurement: 8 iterations, 1 s each # Timeout: 10 min per iteration # Threads: 1 thread, will synchronize iterations # Benchmark mode: Throughput, ops/time # Benchmark: org.jmh.sample.resultformat.JSONFormatBenchmark.calndar # Run progress: 0.00% complete, ETA 00:00:22 # Fork: 1 of 1 # Warmup Iteration 1: 723.338 ops/ms # Warmup Iteration 2: 1588.531 ops/ms # Warmup Iteration 3: 1813.152 ops/ms Iteration 1: 1975.679 ops/ms Iteration 2: 1823.954 ops/ms Iteration 3: 2127.294 ops/ms Iteration 4: 2140.784 ops/ms Iteration 5: 2198.476 ops/ms Iteration 6: 2152.402 ops/ms Iteration 7: 1756.058 ops/ms Iteration 8: 2075.053 ops/ms Result "calndar": 2031.213 ±(99.9%) 312.982 ops/ms [Average] (min, avg, max) = (1756.058, 2031.213, 2198.476), stdev = 163.695 CI (99.9%): [1718.231, 2344.194] (assumes normal distribution) # Warmup: 3 iterations, 1 s each # Measurement: 8 iterations, 1 s each # Timeout: 10 min per iteration # Threads: 1 thread, will synchronize iterations # Benchmark mode: Throughput, ops/time # Benchmark: org.jmh.sample.resultformat.JSONFormatBenchmark.date # Run progress: 50.00% complete, ETA 00:00:12 # Fork: 1 of 1 # Warmup Iteration 1: 35741.999 ops/ms # Warmup Iteration 2: 35740.262 ops/ms # Warmup Iteration 3: 42828.846 ops/ms Iteration 1: 41715.681 ops/ms Iteration 2: 38704.681 ops/ms Iteration 3: 40630.365 ops/ms Iteration 4: 42170.008 ops/ms Iteration 5: 43113.156 ops/ms Iteration 6: 42888.040 ops/ms Iteration 7: 42712.572 ops/ms Iteration 8: 43553.429 ops/ms Result "date": 41935.992 ±(99.9%) 3045.526 ops/ms [Average] (min, avg, max) = (38704.681, 41935.992, 43553.429), stdev = 1592.869 CI (99.9%): [38890.466, 44981.517] (assumes normal distribution) # Run complete. Total time: 00:00:25 Benchmark Mode Cnt Score Error Units JSONFormatBenchmark.calndar thrpt 8 2031.213 ± 312.982 ops/ms JSONFormatBenchmark.date thrpt 8 41935.992 ± 3045.526 ops/ms Benchmark result is saved to jmh-result.json
■ファイルへの出力内容
ファイル(jmh-result.json)には以下の通りJSON形式で出力されます。
(JSON形式の場合CSVやTEXTに比べると細かな情報が出力されます)
[ { "benchmark" : "org.jmh.sample.resultformat.JSONFormatBenchmark.calndar", "mode" : "thrpt", "threads" : 1, "forks" : 1, "warmupIterations" : 3, "warmupTime" : "1 s", "warmupBatchSize" : 1, "measurementIterations" : 8, "measurementTime" : "1 s", "measurementBatchSize" : 1, "primaryMetric" : { "score" : 2031.2125350456186, "scoreError" : 312.98161845723837, "scoreConfidence" : [ 1718.2309165883803, 2344.194153502857 ], "scorePercentiles" : { "0.0" : 1756.0580968714692, "50.0" : 2101.173201603441, "90.0" : 2198.475678280988, "95.0" : 2198.475678280988, "99.0" : 2198.475678280988, "99.9" : 2198.475678280988, "99.99" : 2198.475678280988, "99.999" : 2198.475678280988, "99.9999" : 2198.475678280988, "100.0" : 2198.475678280988 }, "scoreUnit" : "ops/ms", "rawData" : [ [ 1975.6794167720557, 1823.9541417969915, 2127.293876619056, 2140.7844450137263, 2198.475678280988, 2152.4020984228355, 1756.0580968714692, 2075.052526587826 ] ] }, "secondaryMetrics" : { } }, { "benchmark" : "org.jmh.sample.resultformat.JSONFormatBenchmark.date", "mode" : "thrpt", "threads" : 1, "forks" : 1, "warmupIterations" : 3, "warmupTime" : "1 s", "warmupBatchSize" : 1, "measurementIterations" : 8, "measurementTime" : "1 s", "measurementBatchSize" : 1, "primaryMetric" : { "score" : 41935.99154431828, "scoreError" : 3045.5258433819627, "scoreConfidence" : [ 38890.46570093632, 44981.517387700245 ], "scorePercentiles" : { "0.0" : 38704.68115216356, "50.0" : 42441.289768770104, "90.0" : 43553.42888340613, "95.0" : 43553.42888340613, "99.0" : 43553.42888340613, "99.9" : 43553.42888340613, "99.99" : 43553.42888340613, "99.999" : 43553.42888340613, "99.9999" : 43553.42888340613, "100.0" : 43553.42888340613 }, "scoreUnit" : "ops/ms", "rawData" : [ [ 41715.68149483313, 38704.68115216356, 40630.365288648034, 42170.00803633526, 43113.156056319305, 42888.03994163592, 42712.57150120494, 43553.42888340613 ] ] }, "secondaryMetrics" : { } } ]