changeset 1433:cf406468989e

7902040: JMH Core Benchmarks should include more advanced timing tests
author shade
date Fri, 22 Sep 2017 14:30:27 +0200
parents b46a93657b82
children 1ddf31f810a3
files jmh-core-benchmarks/src/main/java/org/openjdk/jmh/benchmarks/CurrentTimeMillisTimerBench.java jmh-core-benchmarks/src/main/java/org/openjdk/jmh/validation/tests/TimingMeasurementsTest.java
diffstat 2 files changed, 134 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core-benchmarks/src/main/java/org/openjdk/jmh/benchmarks/CurrentTimeMillisTimerBench.java	Fri Sep 22 14:30:27 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.benchmarks;
+
+import org.openjdk.jmh.annotations.*;
+
+import java.util.concurrent.TimeUnit;
+
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+@BenchmarkMode(Mode.AverageTime)
+@Warmup(iterations = 5, time = 1)
+@Measurement(iterations = 5, time = 1)
+public class CurrentTimeMillisTimerBench {
+
+    private long last;
+
+    @Benchmark
+    public long latency() {
+        return System.currentTimeMillis();
+    }
+
+    @Benchmark
+    public long granularity() {
+        long lst = last;
+        long cur;
+        do {
+            cur = System.currentTimeMillis();
+        } while (cur == lst);
+        last = cur;
+        return cur;
+    }
+}
--- a/jmh-core-benchmarks/src/main/java/org/openjdk/jmh/validation/tests/TimingMeasurementsTest.java	Thu Sep 07 13:28:40 2017 +0200
+++ b/jmh-core-benchmarks/src/main/java/org/openjdk/jmh/validation/tests/TimingMeasurementsTest.java	Fri Sep 22 14:30:27 2017 +0200
@@ -24,6 +24,10 @@
  */
 package org.openjdk.jmh.validation.tests;
 
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.Threads;
+import org.openjdk.jmh.benchmarks.CurrentTimeMillisTimerBench;
+import org.openjdk.jmh.benchmarks.EmptyBench;
 import org.openjdk.jmh.benchmarks.NanoTimerBench;
 import org.openjdk.jmh.results.Result;
 import org.openjdk.jmh.results.RunResult;
@@ -50,36 +54,88 @@
                 80, 2);
         pw.println();
 
-        {
-            Options opts = new OptionsBuilder()
-                    .parent(parent)
-                    .include(NanoTimerBench.class.getCanonicalName() + ".latency$")
-                    .verbosity(VerboseMode.SILENT)
-                    .build();
+        doNanoTime(pw, parent, "latency", false);
+        doNanoTime(pw, parent, "latency", true);
 
-            RunResult result = new Runner(opts).runSingle();
-            Result r = result.getPrimaryResult();
+        pw.println();
 
-            pw.printf("%50s", "System.nanoTime latency: ");
-            pw.flush();
-            pw.printf("%.2f \u00b1 %.2f ns\n", r.getScore(), r.getScoreError());
+        doCurrentTimeMillis(pw, parent, "latency", false);
+        doCurrentTimeMillis(pw, parent, "latency", true);
+
+        pw.println();
+
+        doNanoTime(pw, parent, "granularity", false);
+        doNanoTime(pw, parent, "granularity", true);
+
+        pw.println();
+
+        doCurrentTimeMillis(pw, parent, "granularity", false);
+        doCurrentTimeMillis(pw, parent, "granularity", true);
+
+        pw.println();
+
+        for (Mode mode : Mode.values()) {
+            if (mode == Mode.All) continue;
+            doEmpty(pw, parent, mode, false);
         }
 
-        {
-            Options opts = new OptionsBuilder()
-                    .parent(parent)
-                    .include(NanoTimerBench.class.getCanonicalName() + ".granularity$")
-                    .verbosity(VerboseMode.SILENT)
-                    .build();
+        pw.println();
 
-            RunResult result = new Runner(opts).runSingle();
-            Result r = result.getPrimaryResult();
-
-            pw.printf("%50s", "System.nanoTime granularity: ");
-            pw.flush();
-            pw.printf("%.2f \u00b1 %.2f ns\n", r.getScore(), r.getScoreError());
+        for (Mode mode : Mode.values()) {
+            if (mode == Mode.All) continue;
+            doEmpty(pw, parent, mode, true);
         }
 
         pw.println();
     }
+
+    private void doEmpty(PrintWriter pw, Options parent, Mode mode, boolean max) throws RunnerException {
+        Options opts = new OptionsBuilder()
+                .parent(parent)
+                .include(EmptyBench.class.getCanonicalName())
+                .verbosity(VerboseMode.SILENT)
+                .threads(max ? Threads.MAX : 1)
+                .mode(mode)
+                .build();
+
+        RunResult result = new Runner(opts).runSingle();
+        Result r = result.getPrimaryResult();
+
+        pw.printf("%50s", mode + ", empty benchmark, " + (max ? "max thread" : "one thread") + ": ");
+        pw.flush();
+        pw.printf("%10.2f \u00b1 %10.2f %s\n", r.getScore(), r.getScoreError(), r.getScoreUnit());
+    }
+
+    void doNanoTime(PrintWriter pw, Options parent, String type, boolean max) throws RunnerException {
+        Options opts = new OptionsBuilder()
+                .parent(parent)
+                .include(NanoTimerBench.class.getCanonicalName() + "." + type + "$")
+                .verbosity(VerboseMode.SILENT)
+                .threads(max ? Threads.MAX : 1)
+                .build();
+
+        RunResult result = new Runner(opts).runSingle();
+        Result r = result.getPrimaryResult();
+
+        pw.printf("%50s", "nanoTime() " + type + ", " + (max ? "max thread" : "one thread") + ": ");
+        pw.flush();
+        pw.printf("%10.2f \u00b1 %10.2f ns\n", r.getScore(), r.getScoreError());
+    }
+
+    void doCurrentTimeMillis(PrintWriter pw, Options parent, String type, boolean max) throws RunnerException {
+        Options opts = new OptionsBuilder()
+                .parent(parent)
+                .include(CurrentTimeMillisTimerBench.class.getCanonicalName() + "." + type + "$")
+                .verbosity(VerboseMode.SILENT)
+                .threads(max ? Threads.MAX : 1)
+                .build();
+
+        RunResult result = new Runner(opts).runSingle();
+        Result r = result.getPrimaryResult();
+
+        pw.printf("%50s", "currentTimeMillis() " + type + ", " + (max ? "max thread" : "one thread") + ": ");
+        pw.flush();
+        pw.printf("%10.2f \u00b1 %10.2f ns\n", r.getScore(), r.getScoreError());
+    }
+
 }