首页 > 应用开发 > Java > java使用 JMH 编写基准测试类并分析结果。
1. 添加依赖
如果你使用 Maven,可以在 pom.xml 添加 JMH 依赖:
<dependencies>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.45</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>17</source>
<target>17</target>
</configuration>
</plugin>
<plugin>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.45</version>
<executions>
<execution>
<goals>
<goal>generate-sources</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
注意:JMH 需要注解处理器,所以 jmh-generator-annprocess 是必须的。
2. 编写基准测试类
假设我们要测试两种字符串连接方式的性能:String + 和 StringBuilder。
import org.openjdk.jmh.annotations.*;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime) // 测试平均执行时间
@OutputTimeUnit(TimeUnit.NANOSECONDS) // 输出时间单位:纳秒
@State(Scope.Thread) // 每个线程独立状态
public class StringConcatBenchmark {
private String base = "hello";
// 使用 String 直接连接
@Benchmark
public String testStringConcat() {
String result = base;
for (int i = 0; i < 10; i++) {
result += " world";
}
return result;
}
// 使用 StringBuilder
@Benchmark
public String testStringBuilder() {
StringBuilder sb = new StringBuilder(base);
for (int i = 0; i < 10; i++) {
sb.append(" world");
}
return sb.toString();
}
}
3. 运行基准测试
JMH 建议不要直接用 IDE 运行,因为它有很多 JVM 调优和 Warmup 的需求。推荐使用 main 方法或 Maven 插件。
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
public class BenchmarkRunner {
public static void main(String[] args) throws Exception {
Options opt = new OptionsBuilder()
.include(StringConcatBenchmark.class.getSimpleName())
.forks(1) // JVM fork次数
.warmupIterations(5) // 预热次数
.measurementIterations(10) // 测量次数
.build();
new Runner(opt).run();
}
}
运行后,你会得到类似如下的输出:
[info] Benchmark Mode Cnt Score Error Units
[info] StringConcatBenchmark.testStringBuilder avgt 10 35.123 ± 1.234 ns/op
[info] StringConcatBenchmark.testStringConcat avgt 10 256.456 ± 10.456 ns/op
4. 分析结果
Mode:基准测试模式,这里是 avgt(Average Time)平均时间。JMH 还支持 Throughput、SampleTime、All 等模式。
Cnt:测量次数
Score:测量值
Error:误差范围
Units:单位(这里是纳秒)
从上面的结果可以看出:
StringBuilder 的性能远高于 String +,因为 String 连接每次都会创建新对象,而 StringBuilder 可以复用缓冲区。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70050070/viewspace-3117516/ ,如需转载,请注明出处,否则将追究法律责任。