本文目录导读:

我来提供一个简单实用的Java性能测试实操案例,使用JMH(Java Microbenchmark Harness)框架。
环境准备
Maven项目配置
<dependencies>
<!-- JMH核心库 -->
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.35</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.35</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
实战案例:字符串拼接性能测试
创建性能测试类
import org.openjdk.jmh.annotations.*;
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;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.Throughput) // 测试吞吐量
@OutputTimeUnit(TimeUnit.SECONDS) // 结果单位
@State(Scope.Thread) // 每个线程独立状态
public class StringConcatBenchmark {
private String baseString = "Hello";
private int count = 1000;
// 测试1: 使用+号拼接
@Benchmark
public String testStringPlus() {
String result = "";
for (int i = 0; i < count; i++) {
result = result + baseString;
}
return result;
}
// 测试2: 使用StringBuilder
@Benchmark
public String testStringBuilder() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < count; i++) {
sb.append(baseString);
}
return sb.toString();
}
// 测试3: 使用StringBuffer
@Benchmark
public String testStringBuffer() {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < count; i++) {
sb.append(baseString);
}
return sb.toString();
}
// 测试4: 使用String.concat()
@Benchmark
public String testStringConcat() {
String result = "";
for (int i = 0; i < count; i++) {
result = result.concat(baseString);
}
return result;
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(StringConcatBenchmark.class.getSimpleName())
.forks(1) // 启动1个JVM进程
.warmupIterations(3) // 预热3次
.measurementIterations(5) // 正式测试5次
.build();
new Runner(opt).run();
}
}
运行测试
# 打包 mvn clean package # 运行 java -jar target/benchmarks.jar
更复杂的性能测试:集合操作对比
import org.openjdk.jmh.annotations.*;
import java.util.*;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime) // 测试平均执行时间
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Thread)
public class CollectionBenchmark {
private List<Integer> list;
private Set<Integer> hashSet;
private Set<Integer> treeSet;
@Setup
public void setup() {
list = new ArrayList<>();
hashSet = new HashSet<>();
treeSet = new TreeSet<>();
// 初始化数据
Random rand = new Random();
for (int i = 0; i < 10000; i++) {
int value = rand.nextInt(10000);
list.add(value);
hashSet.add(value);
treeSet.add(value);
}
}
// 测试ArrayList查找
@Benchmark
public boolean testArrayListContains() {
return list.contains(5000);
}
// 测试HashSet查找
@Benchmark
public boolean testHashSetContains() {
return hashSet.contains(5000);
}
// 测试TreeSet查找
@Benchmark
public boolean testTreeSetContains() {
return treeSet.contains(5000);
}
// 测试ArrayList排序
@Benchmark
public List<Integer> testArrayListSort() {
List<Integer> copy = new ArrayList<>(list);
Collections.sort(copy);
return copy;
}
// 测试TreeSet排序(自动排序)
@Benchmark
public Set<Integer> testTreeSetSort() {
return new TreeSet<>(list);
}
public static void main(String[] args) throws Exception {
Options opt = new OptionsBuilder()
.include(CollectionBenchmark.class.getSimpleName())
.forks(1)
.warmupIterations(3)
.measurementIterations(5)
.build();
new Runner(opt).run();
}
}
运行结果示例
# JMH version: 1.35
# VM version: JDK 11.0.12, OpenJDK 64-Bit Server VM
Benchmark Mode Cnt Score Error Units
StringConcatBenchmark.testStringBuffer thrpt 5 52345.123 ± 1234.567 ops/s
StringConcatBenchmark.testStringBuilder thrpt 5 67890.456 ± 2345.678 ops/s
StringConcatBenchmark.testStringConcat thrpt 5 23456.789 ± 1234.567 ops/s
StringConcatBenchmark.testStringPlus thrpt 5 12345.678 ± 987.654 ops/s
简易性能测试(不使用JMH)
如果不想使用JMH,可以使用简单的时间测量:
public class SimpleBenchmark {
public static void main(String[] args) {
// 测试StringBuilder vs StringBuffer
int iterations = 100000;
long start = System.nanoTime();
testStringBuilder(iterations);
long end = System.nanoTime();
System.out.println("StringBuilder: " + (end - start) / 1_000_000 + " ms");
start = System.nanoTime();
testStringBuffer(iterations);
end = System.nanoTime();
System.out.println("StringBuffer: " + (end - start) / 1_000_000 + " ms");
}
private static void testStringBuilder(int n) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
sb.append("test");
}
}
private static void testStringBuffer(int n) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < n; i++) {
sb.append("test");
}
}
}
最佳实践建议
- 使用JMH:对于精确的性能测试,推荐使用JMH框架
- 预热JVM:让JIT编译优化后再测试
- 多次测试:取平均值,避免偶然因素
- 控制环境:关闭其他程序,保持系统空闲
- 关注趋势:不要过分关注绝对数值,比较相对性能
这个案例简单实用,你可以直接复制代码运行测试你的Java代码性能!
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播