使用Forking可能看到每次运行导致结果都不一样的情况. JMH可以将不同的fork出来的结果放到一起进行统计.
为了更加清晰地看出fork带来的影响, 在下面的测试中我们特意地加大了每次结果的不同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 package testJMH;import org.openjdk.jmh.annotations.Benchmark;import org.openjdk.jmh.annotations.BenchmarkMode;import org.openjdk.jmh.annotations.Fork;import org.openjdk.jmh.annotations.Mode;import org.openjdk.jmh.annotations.OutputTimeUnit;import org.openjdk.jmh.annotations.Scope;import org.openjdk.jmh.annotations.Setup;import org.openjdk.jmh.annotations.State;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;@State(Scope.Thread) @BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.MILLISECONDS) public class JMHSample_13_RunToRun { @State(Scope.Thread) public static class SleepyState { public long sleepTime; @Setup public void setup () { sleepTime = (long ) (Math.random() * 1000 ); } } @Benchmark @Fork(1) public void baseline (SleepyState s) throws InterruptedException { TimeUnit.MILLISECONDS.sleep(s.sleepTime); } @Benchmark @Fork(3) public void fork_1 (SleepyState s) throws InterruptedException { TimeUnit.MILLISECONDS.sleep(s.sleepTime); } public static void main (String[] args) throws RunnerException { Options opt = new OptionsBuilder() .include(JMHSample_13_RunToRun.class.getSimpleName()) .warmupIterations(0 ) .measurementIterations(5 ) .build(); new Runner(opt).run(); } }
执行结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 # Measurement: 5 iterations, 1 s each # Timeout: 10 min per iteration # Threads: 1 thread, will synchronize iterations # Benchmark mode: Average time, time/op # Benchmark: testJMH.JMHSample_13_RunToRun.baseline # Run progress: 0.00 % complete, ETA 00 :00 :20 # Fork: 1 of 1 Iteration 1 : 419.858 ms/op Iteration 2 : 420.190 ms/op Iteration 3 : 420.376 ms/op Iteration 4 : 420.728 ms/op Iteration 5 : 421.622 ms/op Result "baseline" : 420.555 ±(99.9 %) 2.597 ms/op [Average] (min, avg, max) = (419.858 , 420.555 , 421.622 ), stdev = 0.675 CI (99.9 %): [417.958 , 423.152 ] (assumes normal distribution) # Measurement: 5 iterations, 1 s each # Timeout: 10 min per iteration # Threads: 1 thread, will synchronize iterations # Benchmark mode: Average time, time/op # Benchmark: testJMH.JMHSample_13_RunToRun.fork_1 # Run progress: 25.00 % complete, ETA 00 :00 :20 # Fork: 1 of 3 Iteration 1 : 817.066 ms/op Iteration 2 : 820.061 ms/op Iteration 3 : 818.648 ms/op Iteration 4 : 818.029 ms/op Iteration 5 : 819.518 ms/op # Run progress: 50.00 % complete, ETA 00 :00 :16 # Fork: 2 of 3 Iteration 1 : 406.259 ms/op Iteration 2 : 406.128 ms/op Iteration 3 : 405.895 ms/op Iteration 4 : 406.083 ms/op Iteration 5 : 405.879 ms/op # Run progress: 75.00 % complete, ETA 00 :00 :07 # Fork: 3 of 3 Iteration 1 : 149.923 ms/op Iteration 2 : 150.784 ms/op Iteration 3 : 150.753 ms/op Iteration 4 : 150.717 ms/op Iteration 5 : 150.718 ms/op Result "fork_1" : 458.431 ±(99.9 %) 304.586 ms/op [Average] (min, avg, max) = (149.923 , 458.431 , 820.061 ), stdev = 284.910 CI (99.9 %): [153.845 , 763.016 ] (assumes normal distribution) # Run complete. Total time: 00 :00 :28 Benchmark Mode Cnt Score Error Units testJMH.JMHSample_13_RunToRun.baseline avgt 5 420.555 ± 2.597 ms/op testJMH.JMHSample_13_RunToRun.fork_1 avgt 15 458.431 ± 304.586 ms/op
从上面的结果中我们可以看到, 在fork_1中, 运行了三次, 每次随机出的sleep时间都不一样, 而最后统计的时候, 却统计的是三次结果的合