changeset 211:cd800437c7de

Support ResultFormats.
author shade
date Thu, 24 Oct 2013 14:59:34 +0400
parents a38d89ed91ce
children c1c8be353c1c
files jmh-core/src/main/java/org/openjdk/jmh/Main.java jmh-core/src/main/java/org/openjdk/jmh/logic/results/RunResult.java jmh-core/src/main/java/org/openjdk/jmh/output/results/CSVResultFormat.java jmh-core/src/main/java/org/openjdk/jmh/output/results/NoneResultFormat.java jmh-core/src/main/java/org/openjdk/jmh/output/results/ResultFormat.java jmh-core/src/main/java/org/openjdk/jmh/output/results/ResultFormatFactory.java jmh-core/src/main/java/org/openjdk/jmh/output/results/ResultFormatType.java jmh-core/src/main/java/org/openjdk/jmh/runner/Runner.java jmh-core/src/main/java/org/openjdk/jmh/runner/options/ChainedOptionsBuilder.java jmh-core/src/main/java/org/openjdk/jmh/runner/options/CommandLineOptions.java jmh-core/src/main/java/org/openjdk/jmh/runner/options/Options.java jmh-core/src/main/java/org/openjdk/jmh/runner/options/OptionsBuilder.java jmh-core/src/main/java/org/openjdk/jmh/runner/parameters/Defaults.java
diffstat 13 files changed, 352 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/jmh-core/src/main/java/org/openjdk/jmh/Main.java	Wed Oct 23 21:55:29 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/Main.java	Thu Oct 24 14:59:34 2013 +0400
@@ -26,6 +26,7 @@
 
 import org.kohsuke.args4j.CmdLineException;
 import org.openjdk.jmh.output.OutputFormatType;
+import org.openjdk.jmh.output.results.ResultFormatType;
 import org.openjdk.jmh.profile.ProfilerFactory;
 import org.openjdk.jmh.runner.Runner;
 import org.openjdk.jmh.runner.RunnerException;
@@ -50,7 +51,7 @@
             cmdOptions.parseArguments(argv);
 
             // list output formats?
-            if (cmdOptions.shouldListFormats()) {
+            if (cmdOptions.shouldListOutputFormats()) {
                 StringBuilder sb = new StringBuilder();
 
                 for (OutputFormatType f : OutputFormatType.values()) {
@@ -63,6 +64,19 @@
                 return;
             }
 
+            if (cmdOptions.shouldListResultFormats()) {
+                StringBuilder sb = new StringBuilder();
+
+                for (ResultFormatType f : ResultFormatType.values()) {
+                    sb.append(f.toString().toLowerCase());
+                    sb.append(", ");
+                }
+                sb.setLength(sb.length() - 2);
+
+                System.out.println("Available formats: " + sb.toString());
+                return;
+            }
+
             // list available profilers?
             if (cmdOptions.shouldListProfilers()) {
                 StringBuilder sb = new StringBuilder();
--- a/jmh-core/src/main/java/org/openjdk/jmh/logic/results/RunResult.java	Wed Oct 23 21:55:29 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/logic/results/RunResult.java	Thu Oct 24 14:59:34 2013 +0400
@@ -143,4 +143,8 @@
     public BenchmarkRecord getBenchmark() {
         return benchmark;
     }
+
+    public int getIterationCount() {
+        return params.getCount();
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/output/results/CSVResultFormat.java	Thu Oct 24 14:59:34 2013 +0400
@@ -0,0 +1,84 @@
+/*
+ * 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.output.results;
+
+import org.openjdk.jmh.logic.results.RunResult;
+import org.openjdk.jmh.runner.BenchmarkRecord;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Map;
+
+public class CSVResultFormat implements ResultFormat {
+
+    private final String output;
+
+    public CSVResultFormat(String output) {
+        this.output = output;
+    }
+
+    @Override
+    public void writeOut(Map<BenchmarkRecord, RunResult> results) {
+        PrintWriter pw = null;
+        try  {
+            pw = new PrintWriter(output);
+
+            pw.println("\"Benchmark\", \"Mode\", \"Threads\", \"Iterations\", \"Iteration time\", \"Mean\", \"Mean Error (95%)\", \"Mean Error (99%)\", \"Unit\"");
+
+            for (BenchmarkRecord br : results.keySet()) {
+                RunResult runResult = results.get(br);
+
+                pw.print("\"");
+                pw.print(br.getUsername());
+                pw.print("\", \"");
+                pw.print(br.getMode().shortLabel());
+                pw.print("\", ");
+                pw.print(runResult.getThreads());
+                pw.print(", ");
+                pw.print(runResult.getIterationCount());
+                pw.print(", \"");
+                pw.print(runResult.getTime());
+                pw.print("\", ");
+                pw.print(runResult.getPrimaryResult().getStatistics().getMean());
+                pw.print(", ");
+                pw.print(runResult.getPrimaryResult().getStatistics().getMeanError(0.95));
+                pw.print(", ");
+                pw.print(runResult.getPrimaryResult().getStatistics().getMeanError(0.99));
+                pw.print(", \"");
+                pw.print(runResult.getPrimaryResult().getScoreUnit());
+                pw.println("\"");
+            }
+
+        } catch (IOException e) {
+            throw new IllegalStateException(e);
+        } finally {
+            if (pw != null) {
+                pw.close();
+            }
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/output/results/NoneResultFormat.java	Thu Oct 24 14:59:34 2013 +0400
@@ -0,0 +1,37 @@
+/*
+ * 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.output.results;
+
+import org.openjdk.jmh.logic.results.RunResult;
+import org.openjdk.jmh.runner.BenchmarkRecord;
+
+import java.util.Map;
+
+public class NoneResultFormat implements ResultFormat {
+    @Override
+    public void writeOut(Map<BenchmarkRecord, RunResult> results) {
+        // do nothing
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/output/results/ResultFormat.java	Thu Oct 24 14:59:34 2013 +0400
@@ -0,0 +1,36 @@
+/*
+ * 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.output.results;
+
+import org.openjdk.jmh.logic.results.RunResult;
+import org.openjdk.jmh.runner.BenchmarkRecord;
+
+import java.util.Map;
+
+public interface ResultFormat {
+
+    void writeOut(Map<BenchmarkRecord, RunResult> results);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/output/results/ResultFormatFactory.java	Thu Oct 24 14:59:34 2013 +0400
@@ -0,0 +1,42 @@
+/*
+ * 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.output.results;
+
+public class ResultFormatFactory {
+
+    private ResultFormatFactory() {}
+
+    public static ResultFormat getInstance(ResultFormatType type, String output) {
+        switch (type) {
+            case NONE:
+                return new NoneResultFormat();
+            case CSV:
+                return new CSVResultFormat(output);
+            default:
+                throw new IllegalStateException("Unsupported result format: " + type);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/output/results/ResultFormatType.java	Thu Oct 24 14:59:34 2013 +0400
@@ -0,0 +1,37 @@
+/*
+ * 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.output.results;
+
+public enum ResultFormatType {
+
+    NONE,
+    CSV,
+    ;
+
+    public static ResultFormatType defaultType() {
+        return NONE;
+    }
+
+}
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/Runner.java	Wed Oct 23 21:55:29 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/Runner.java	Thu Oct 24 14:59:34 2013 +0400
@@ -32,6 +32,8 @@
 import org.openjdk.jmh.logic.results.RunResult;
 import org.openjdk.jmh.output.OutputFormatFactory;
 import org.openjdk.jmh.output.format.OutputFormat;
+import org.openjdk.jmh.output.results.ResultFormat;
+import org.openjdk.jmh.output.results.ResultFormatFactory;
 import org.openjdk.jmh.runner.options.Options;
 import org.openjdk.jmh.runner.options.WarmupMode;
 import org.openjdk.jmh.runner.parameters.Defaults;
@@ -202,6 +204,9 @@
         out.flush();
         out.close();
 
+        ResultFormat resultFormat = ResultFormatFactory.getInstance(options.getResultFormat(), options.getResult());
+        resultFormat.writeOut(results);
+
         return results;
     }
 
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/options/ChainedOptionsBuilder.java	Wed Oct 23 21:55:29 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/options/ChainedOptionsBuilder.java	Thu Oct 24 14:59:34 2013 +0400
@@ -26,6 +26,7 @@
 
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.output.OutputFormatType;
+import org.openjdk.jmh.output.results.ResultFormatType;
 import org.openjdk.jmh.profile.ProfilerType;
 import org.openjdk.jmh.runner.parameters.TimeValue;
 
@@ -65,6 +66,13 @@
     ChainedOptionsBuilder outputFormat(OutputFormatType type);
 
     /**
+     * ResultFormatType to use in the run
+     * @param type resultformat type
+     * @return builder
+     */
+    ChainedOptionsBuilder resultFormat(ResultFormatType type);
+
+    /**
      * Output filename to write the run log to
      * @param filename file name
      * @return builder
@@ -72,6 +80,13 @@
     ChainedOptionsBuilder output(String filename);
 
     /**
+     * Output filename to write the result to
+     * @param filename file name
+     * @return builder
+     */
+    ChainedOptionsBuilder result(String filename);
+
+    /**
      * Should do GC between measurementIterations?
      * @param value flag
      * @return builder
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/options/CommandLineOptions.java	Wed Oct 23 21:55:29 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/options/CommandLineOptions.java	Thu Oct 24 14:59:34 2013 +0400
@@ -30,6 +30,7 @@
 import org.kohsuke.args4j.Option;
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.output.OutputFormatType;
+import org.openjdk.jmh.output.results.ResultFormatType;
 import org.openjdk.jmh.profile.ProfilerType;
 import org.openjdk.jmh.runner.options.handlers.BenchmarkModeTypeOptionHandler;
 import org.openjdk.jmh.runner.options.handlers.BooleanOptionHandler;
@@ -104,7 +105,7 @@
     @Option(name = "-foe", usage = "Fail the harness on benchmark erro?", handler = BooleanOptionHandler.class)
     protected boolean failOnError = false;
 
-    @Option(name = "-prof", aliases = {"--useprofiler"}, multiValued = false, usage = "Use profilers for collecting additional info, use --listprofilers to list available profilers", handler = ProfilersOptionHandler.class)
+    @Option(name = "-prof", aliases = {"--useprofiler"}, multiValued = false, usage = "Use profilers for collecting additional info, use --listProfilers to list available profilers", handler = ProfilersOptionHandler.class)
     protected Set<ProfilerType> profilers = EnumSet.noneOf(ProfilerType.class);
 
     @Option(name = "-tu", aliases = {"--timeunit"}, usage = "Output time unit. Available values: m, s, ms, us, ns", handler = TimeUnitOptionHandler.class)
@@ -125,9 +126,15 @@
     @Option(name = "-o", aliases = {"--output"}, metaVar = "FILE", usage = "Redirect output to FILE")
     protected String output = null;
 
-    @Option(name = "-of", aliases = {"--outputformat"}, metaVar = "FORMAT", usage = "Format to use for output, use --listformats to list available formats")
+    @Option(name = "-rff", aliases = {"--result"}, metaVar = "FILE", usage = "Redirect results to FILE")
+    protected String result = Defaults.RESULT_FILE;
+
+    @Option(name = "-of", aliases = {"--outputformat"}, metaVar = "FORMAT", usage = "Format to use for output, use --listOutputFormats to list available formats")
     protected OutputFormatType outputFormat = OutputFormatType.defaultType();
 
+    @Option(name = "-rf", aliases = {"--resultformat"}, metaVar = "FORMAT", usage = "Format to use for results, use --listResultFormats to list available formats")
+    protected ResultFormatType resultFormat = ResultFormatType.defaultType();
+
     @Option(name = "--jvm", metaVar = "JVM", usage = "Custom JVM to use with fork.")
     protected String jvm = null;
 
@@ -150,13 +157,16 @@
     @Option(name = "-l", aliases = {"--list"}, usage = "List available microbenchmarks and exit. Filter using available regexps.")
     protected boolean list = false;
 
-    @Option(name = "--listformats", usage = "List available output formats")
-    protected boolean listFormats = false;
+    @Option(name = "--listOutputFormats", usage = "List available output formats")
+    protected boolean listOutputFormats = false;
+
+    @Option(name = "--listResultFormats", usage = "List available result formats")
+    protected boolean listResultFormats = false;
 
     @Option(name = "-h", aliases = {"--help"}, usage = "Display help")
     protected boolean help = false;
 
-    @Option(name = "--listprofilers", usage = "List available profilers")
+    @Option(name = "--listProfilers", usage = "List available profilers")
     protected boolean listProfilers = false;
 
     /**
@@ -321,13 +331,27 @@
         return outputFormat;
     }
 
+    @Override
+    public ResultFormatType getResultFormat() {
+        return resultFormat;
+    }
+
+    @Override
+    public String getResult() {
+        return result;
+    }
+
     /**
      * Getter
      *
      * @return the value
      */
-    public boolean shouldListFormats() {
-        return listFormats;
+    public boolean shouldListOutputFormats() {
+        return listOutputFormats;
+    }
+
+    public boolean shouldListResultFormats() {
+        return listResultFormats;
     }
 
     /**
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/options/Options.java	Wed Oct 23 21:55:29 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/options/Options.java	Thu Oct 24 14:59:34 2013 +0400
@@ -26,6 +26,7 @@
 
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.output.OutputFormatType;
+import org.openjdk.jmh.output.results.ResultFormatType;
 import org.openjdk.jmh.profile.ProfilerType;
 import org.openjdk.jmh.runner.parameters.TimeValue;
 
@@ -61,6 +62,18 @@
     String getOutput();
 
     /**
+     * Result format to use
+     * @return format type
+     */
+    ResultFormatType getResultFormat();
+
+    /**
+     * Which file to use for dumping the result
+     * @return file name; null if not defined
+     */
+    String getResult();
+
+    /**
      * Should force GC between iterations?
      * @return should GC?
      */
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/options/OptionsBuilder.java	Wed Oct 23 21:55:29 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/options/OptionsBuilder.java	Thu Oct 24 14:59:34 2013 +0400
@@ -26,7 +26,9 @@
 
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.output.OutputFormatType;
+import org.openjdk.jmh.output.results.ResultFormatType;
 import org.openjdk.jmh.profile.ProfilerType;
+import org.openjdk.jmh.runner.parameters.Defaults;
 import org.openjdk.jmh.runner.parameters.TimeValue;
 
 import java.util.ArrayList;
@@ -115,6 +117,36 @@
 
     // ---------------------------------------------------------------------------
 
+    private ResultFormatType rfType = ResultFormatType.defaultType();
+
+    @Override
+    public ChainedOptionsBuilder resultFormat(ResultFormatType type) {
+        rfType = type;
+        return this;
+    }
+
+    @Override
+    public ResultFormatType getResultFormat() {
+        return rfType;
+    }
+
+    // ---------------------------------------------------------------------------
+
+    private String result = Defaults.RESULT_FILE;
+
+    @Override
+    public ChainedOptionsBuilder result(String filename) {
+        this.result = filename;
+        return this;
+    }
+
+    @Override
+    public String getResult() {
+        return result;
+    }
+
+    // ---------------------------------------------------------------------------
+
     private boolean shouldDoGC;
 
     @Override
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/parameters/Defaults.java	Wed Oct 23 21:55:29 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/parameters/Defaults.java	Thu Oct 24 14:59:34 2013 +0400
@@ -54,4 +54,5 @@
 
     public static final boolean SHOULD_SYNCH_ITERATIONS = true;
 
+    public static final String RESULT_FILE = "jmh.out";
 }