什么是基准测试?
这里说道的基准测试Benchmark其实是微基准测试Micro-Benchmark。
简单点说,就是我们看到或听到很多人说什么方式去使用Java的性能好呀,不要猜,动手来测吧!
详细的概念可以参见:https://github.com/google/caliper/wiki/JavaMicrobenchmarks
健壮的Java基准测试
https://www.ibm.com/developerworks/cn/java/j-benchmark1.html
https://www.ibm.com/developerworks/cn/java/j-benchmark2/index.html
我们可以看到影响基准测试的因素比较多,包括代码预热、编译器动态优化、资源回收(GC)、文件缓存、电源、其他程序,JVM的VM选项等等。我们在进行基准测试前需要关注其对产生结果的影响。
JMH是什么?
JMH是OpenJDK提供的基准测试工具,是由Oracle实现JIT的相同人员开发的。
怎么使用?
maven方式:
1<!-- https://mvnrepository.com/artifact/org.openjdk.jmh/jmh-core --> 2<dependency> 3 <groupId>org.openjdk.jmh</groupId> 4 <artifactId>jmh-core</artifactId> 5 <version>1.20</version> 6</dependency> 7 <dependency> 8 <groupId>org.openjdk.jmh</groupId> 9 <artifactId>jmh-generator-annprocess</artifactId> 10 <version>1.20</version> 11</dependency>
然后在需要基准测试的方法加入@Benchmark注解,IDE中测试Run(不要使用Debug模式运行):
我们举个例子,比如我们常说使用string +追加字符串,比如StringBuilder效率高,是真的这样吗?
不要猜,来测呀!
1package io.flysium.jmh.sample; 2 3import java.util.concurrent.TimeUnit; 4import org.openjdk.jmh.annotations.Benchmark; 5import org.openjdk.jmh.annotations.BenchmarkMode; 6import org.openjdk.jmh.annotations.Measurement; 7import org.openjdk.jmh.annotations.Mode; 8import org.openjdk.jmh.annotations.OutputTimeUnit; 9import org.openjdk.jmh.annotations.Threads; 10import org.openjdk.jmh.annotations.Warmup; 11import org.openjdk.jmh.runner.Runner; 12import org.openjdk.jmh.runner.RunnerException; 13import org.openjdk.jmh.runner.options.Options; 14import org.openjdk.jmh.runner.options.OptionsBuilder; 15import org.openjdk.jmh.samples.JMHSample_01_HelloWorld; 16 17/** 18 * @author Sven Augustus 19 * @version 1.0 20 * @since JDK 1.8 21 */ 22@BenchmarkMode(Mode.Throughput) 23@Warmup(iterations = 3) 24@Measurement(iterations = 10, time = 5, timeUnit = TimeUnit.SECONDS) 25//@Threads(16) 26@OutputTimeUnit(TimeUnit.MILLISECONDS) 27public class QuickStart { 28 29 @Benchmark 30 public String testStringAdd() { 31 String a = ""; 32 for (int i = 0; i < 10; i++) { 33 a += i; 34 } 35 return a; 36 } 37 38 @Benchmark 39 public String testStringBuilderAdd() { 40 StringBuilder sb = new StringBuilder(); 41 for (int i = 0; i < 10; i++) { 42 sb.append(i); 43 } 44 return sb.toString(); 45 } 46 47 public static void main(String[] args) throws RunnerException { 48 Options opt = new OptionsBuilder() 49 .include(QuickStart.class.getSimpleName()) 50 .forks(1) 51 .build(); 52 new Runner(opt).run(); 53 } 54 55}
结果:

很明显,我们看到了StringBuilder效率确实快。图中ops/ms意思是每毫秒执行的方法次数。
更多例子
JMH官方例子:
http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/
其他参考:
http://www.importnew.com/12548.html
http://irfen.me/java-jmh-simple-microbenchmark/
https://blog.csdn.net/hfmbook/article/details/70209150