JMH是一個用于構建,運行和分析基于Java及其他JVM語言的基準測試工具。它也是OpenJDK項目的一部分。
要運行JMH基準測試,推薦的方法是使用Maven來構建一個測試項目。生成相關的依賴信息,以及簡單的測試骨架代碼。由于這種方式比較純粹,項目是全新的、自動生成的,不受其他環境的影響,因此比較可靠。
使用Maven創建一個JMH基準測試項目
使用以下Maven命令創建一個JMH測試項目。
$ mvn archetype:generate -DinteractiveMode=false \ -DarchetypeGroupId=org.openjdk.jmh -DarchetypeArtifactId=jmh-java-benchmark-archetype -DarchetypeVersion=1.21 \ -DgroupId=org.sample -DartifactId=test -Dversion=1.0 |
其中,以archetype開頭的3個參數為JMH依賴信息,JMH版本號為1.21。
-DarchetypeGroupId=org.openjdk.jmh -DarchetypeArtifactId=jmh-java-benchmark-archetype -DarchetypeVersion=1.21 |
最后3個參數為測試項目的信息,分別是默認包名、項目名和版本號。
-DgroupId=org.sample -DartifactId=test -Dversion=1.0 |
1)生成的pom.xml主要代碼如下
<groupId>org.sample</groupId> <artifactId>test</artifactId> <version>1.0</version> <packaging>jar</packaging> <name>JMH benchmark sample: Java</name> <!-- This is the demo/sample template build script for building Java benchmarks with JMH. Edit as needed. --> <dependencies> <dependency> <groupId>org.openjdk.jmh</groupId> <artifactId>jmh-core</artifactId> <version>${jmh.version}</version> </dependency> <dependency> <groupId>org.openjdk.jmh</groupId> <artifactId>jmh-generator-annprocess</artifactId> <version>${jmh.version}</version> <scope>provided</scope> </dependency> </dependencies> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- JMH version to use with this project. --> <jmh.version>1.21</jmh.version> <!-- Java source/target to use for compilation. --> <javac.target>1.8</javac.target> <!-- Name of the benchmark Uber-JAR to generate. --> <uberjar.name>benchmarks</uberjar.name> </properties> |
2)生成一個MyBenchmark.java類
默認生成一個測試類,類里面僅有一個測試方法testMethod(),該方法帶有一個@Benchmark注解。
可以在testMethod()方法內添加想要測試的代碼邏輯,執行基準測試的時候將會執行該方法。
package org.sample; import org.openjdk.jmh.annotations.Benchmark; public class MyBenchmark { @Benchmark public void testMethod() { // This is a demo/sample template for building your JMH benchmarks. Edit as needed. // Put your benchmark code here. } } |
編譯構建項目
編譯項目。
$ cd test/ $ mvn clean verify |
生成目標信息如下。
$ ls target/ benchmarks.jar generated-sources/ maven-status/ classes/ maven-archiver/ test-1.0.jar |
其中,benchmarks.jar包含了待測試代碼的class文件,以及執行測試需要依賴的JMH相關class文件。
執行基準測試
在完成代碼的構建之后,可以執行以下命令執行測試。
執行命令后,JMH將會掃描并找到所有待測試的代碼,并執行測試相應的方法。
執行的過程中,會輸出測試相關數據,總體上可以分為3部分:
測試環境配置信息;
每輪測試的具體情況;
整體測試結果。
測試環境配置信息
通過輸出信息,可以了解到測環境試配置如下:
JMH版本號為1.21;
JDK版本號為1.8.0_121;
熱身:每輪測試進行5次熱身迭代,每次迭代的時間為10s;
真正的基準測試:每輪測試進行5次基準迭代,每次迭代的時間為10s;
超時:每次迭代的超時時間為10分鐘;
線程:執行測試的線程數為1,順序執行每輪測試;
基準測試模式:默認進行吞吐量測試;
基準測試方法:org.sample.MyBenchmark.testMethod
$ java -jar target/benchmarks.jar # JMH version: 1.21 # VM version: JDK 1.8.0_121, Java HotSpot(TM) 64-Bit Server VM, 25.121-b13 # VM invoker: C:\SDK\jdk1.8.0_121\jre\bin\java.exe # VM options: <none> # Warmup: 5 iterations, 10 s each # Measurement: 5 iterations, 10 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:08:20 # Fork: 1 of 5 # Warmup Iteration 1: 1576551518.400 ops/s # Warmup Iteration 2: 1529719054.021 ops/s # Warmup Iteration 3: 1666073877.889 ops/s # Warmup Iteration 4: 1640435331.734 ops/s # Warmup Iteration 5: 1638832864.366 ops/s Iteration 1: 1625641896.790 ops/s Iteration 2: 1533553941.136 ops/s Iteration 3: 1592753193.369 ops/s Iteration 4: 1632034409.677 ops/s Iteration 5: 1595397793.688 ops/s # Run progress: 20.00% complete, ETA 00:06:44 # Fork: 2 of 5 # Warmup Iteration 1: 1464189837.888 ops/s # Warmup Iteration 2: 1568131253.159 ops/s # Warmup Iteration 3: 1512431773.674 ops/s # Warmup Iteration 4: 1624047095.614 ops/s # Warmup Iteration 5: 1599319656.890 ops/s Iteration 1: 1549565370.435 ops/s Iteration 2: 1479685624.920 ops/s Iteration 3: 1546268750.693 ops/s Iteration 4: 1624076911.097 ops/s Iteration 5: 1547120121.585 ops/s # Run progress: 40.00% complete, ETA 00:05:03 # Fork: 3 of 5 # Warmup Iteration 1: 1635927468.533 ops/s # Warmup Iteration 2: 2117152863.952 ops/s # Warmup Iteration 3: 2191950165.947 ops/s # Warmup Iteration 4: 2117139604.170 ops/s # Warmup Iteration 5: 1966743425.584 ops/s Iteration 1: 2094680040.904 ops/s Iteration 2: 2192052945.492 ops/s Iteration 3: 2215953631.021 ops/s Iteration 4: 2187306852.799 ops/s Iteration 5: 2225823062.910 ops/s # Run progress: 60.00% complete, ETA 00:03:22 # Fork: 4 of 5 # Warmup Iteration 1: 2215218138.467 ops/s # Warmup Iteration 2: 2060564779.974 ops/s # Warmup Iteration 3: 2128581454.514 ops/s # Warmup Iteration 4: 2136226391.233 ops/s # Warmup Iteration 5: 2190998438.402 ops/s Iteration 1: 2149230777.286 ops/s Iteration 2: 1962048343.572 ops/s Iteration 3: 1632748373.818 ops/s Iteration 4: 2069121825.198 ops/s Iteration 5: 2137771926.471 ops/s # Run progress: 80.00% complete, ETA 00:01:40 # Fork: 5 of 5 # Warmup Iteration 1: 2175401658.601 ops/s # Warmup Iteration 2: 1998795501.979 ops/s # Warmup Iteration 3: 2207762443.100 ops/s # Warmup Iteration 4: 2158909861.991 ops/s # Warmup Iteration 5: 2172243775.496 ops/s Iteration 1: 2088490735.383 ops/s Iteration 2: 2055344061.187 ops/s Iteration 3: 2143537771.341 ops/s Iteration 4: 2249547560.686 ops/s Iteration 5: 2204700995.400 ops/s Result "org.sample.MyBenchmark.testMethod": 1893378276.674 ±(99.9%) 219511037.182 ops/s [Average] (min, avg, max) = (1479685624.920, 1893378276.674, 2249547560.686), stdev = 293040954.374 CI (99.9%): [1673867239.493, 2112889313.856] (assumes normal distribution) # Run complete. Total time: 00:08:24 REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial experiments, perform baseline and negative tests that provide experimental control, make sure the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts. Do not assume the numbers tell you what you want them to tell. Benchmark Mode Cnt Score Error Units MyBenchmark.testMethod thrpt 25 1893378276.674 ± 219511037.182 ops/s |
每輪測試的具體情況
總共運行了5輪測試,每輪測試的輸出信息大致如下:
當前的測試進度,以及剩下的測試時間;
當前是第幾輪測試;
熱身標識和序號,以及QPS;
基準測試標識和序號,以及QPS。
進行多輪測試,可以確保結果不是隨機的。
每一輪會先執行熱身,防止受啟動和運行波動的影響
熱身之后的基準迭代測試,才會反應到測試結果中。
每1次迭代時間為10s,每一輪進行5次熱身5次基準測試,大約占用100s。
整體測試結果
匯總本次基準測試的整體情況,包括測試運行時間和每個測試方法的QPS等信息。
Result塊是基準測試目標方法的測試結果,其中(min, avg, max)是最小、平均和最大QPS。
本次基準測試,總共運行了8分鐘24秒。
MyBenchmark.testMethod進行的是吞吐量(thrpt)測試,進行了25次基準迭代。
本文內容不用于商業目的,如涉及知識產權問題,請權利人聯系51Testing小編(021-64471599-8017),我們將立即處理