changeset 1327:c050a47b2b37

7901421: Reconsider the marshalling scheme for BenchmarkListEntry
author shade
date Wed, 13 Jul 2016 19:35:00 +0300
parents cffb77974716
children 1345ad5a0155
files jmh-core/src/main/java/org/openjdk/jmh/runner/AbstractResourceReader.java jmh-core/src/main/java/org/openjdk/jmh/runner/BenchmarkList.java jmh-core/src/main/java/org/openjdk/jmh/runner/BenchmarkListEntry.java jmh-core/src/main/java/org/openjdk/jmh/runner/CompilerHints.java jmh-core/src/main/java/org/openjdk/jmh/util/Optional.java jmh-core/src/main/java/org/openjdk/jmh/util/lines/Constants.java jmh-core/src/main/java/org/openjdk/jmh/util/lines/TestLineReader.java jmh-core/src/main/java/org/openjdk/jmh/util/lines/TestLineWriter.java jmh-core/src/test/java/org/openjdk/jmh/runner/TestBenchmarkList.java jmh-core/src/test/java/org/openjdk/jmh/util/TestFileUtils.java jmh-core/src/test/java/org/openjdk/jmh/util/TestLineTest.java jmh-core/src/test/resources/org/openjdk/jmh/runner/MicroBenchmarks
diffstat 12 files changed, 721 insertions(+), 255 deletions(-) [+]
line wrap: on
line diff
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/AbstractResourceReader.java	Wed Jul 13 19:31:07 2016 +0300
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/AbstractResourceReader.java	Wed Jul 13 19:35:00 2016 +0300
@@ -24,12 +24,7 @@
  */
 package org.openjdk.jmh.runner;
 
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
+import java.io.*;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -40,10 +35,12 @@
 
     private final String file;
     private final String resource;
+    private final String strings;
 
-    protected AbstractResourceReader(String file, String resource) {
+    protected AbstractResourceReader(String file, String resource, String strings) {
         this.file = file;
         this.resource = resource;
+        this.strings = strings;
     }
 
     /**
@@ -52,6 +49,10 @@
      * @return a correct Reader instance
      */
     protected List<Reader> getReaders() {
+        if (strings != null) {
+            return Collections.<Reader>singletonList(new StringReader(strings));
+        }
+
         if (file != null) {
             try {
                 return Collections.<Reader>singletonList(new FileReader(file));
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/BenchmarkList.java	Wed Jul 13 19:31:07 2016 +0300
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/BenchmarkList.java	Wed Jul 13 19:35:00 2016 +0300
@@ -29,12 +29,7 @@
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.Reader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
+import java.util.*;
 import java.util.regex.Pattern;
 
 /**
@@ -49,16 +44,20 @@
         return fromResource(BENCHMARK_LIST);
     }
 
-    public static BenchmarkList fromResource(String resource) {
-        return new BenchmarkList(null, resource);
+    public static BenchmarkList fromFile(String file) {
+        return new BenchmarkList(file, null, null);
     }
 
-    public static BenchmarkList fromFile(String file) {
-        return new BenchmarkList(file, null);
+    public static BenchmarkList fromResource(String resource) {
+        return new BenchmarkList(null, resource, null);
     }
 
-    private BenchmarkList(String file, String resource) {
-        super(file, resource);
+    public static BenchmarkList fromString(String strings) {
+        return new BenchmarkList(null, null, strings);
+    }
+
+    private BenchmarkList(String file, String resource, String strings) {
+        super(file, resource, strings);
     }
 
     /**
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/BenchmarkListEntry.java	Wed Jul 13 19:31:07 2016 +0300
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/BenchmarkListEntry.java	Wed Jul 13 19:35:00 2016 +0300
@@ -27,18 +27,16 @@
 import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.runner.options.TimeValue;
 import org.openjdk.jmh.util.Optional;
-import org.openjdk.jmh.util.Utils;
+import org.openjdk.jmh.util.lines.TestLineReader;
+import org.openjdk.jmh.util.lines.TestLineWriter;
 
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Map;
-import java.util.TreeMap;
 import java.util.concurrent.TimeUnit;
 
 public class BenchmarkListEntry implements Comparable<BenchmarkListEntry> {
 
-    private static final String BR_SEPARATOR = "===,===";
-
     private final String userClassQName;
     private final String generatedClassQName;
     private final String method;
@@ -100,53 +98,67 @@
     }
 
     public BenchmarkListEntry(String line) {
-        String[] args = line.split(BR_SEPARATOR);
+        this.workloadParams = new WorkloadParams();
 
-        if (args.length != 23) {
-            throw new IllegalStateException("Mismatched format for the line: " + line);
+        TestLineReader reader = new TestLineReader(line);
+
+        if (!reader.isCorrect()) {
+            throw new IllegalStateException("Unable to parse the line: " + line);
         }
 
-        this.workloadParams = new WorkloadParams();
-
-        int idx = 0;
-        this.userClassQName = args[idx++].trim();
-        this.generatedClassQName = args[idx++].trim();
-        this.method = args[idx++].trim();
-        this.mode = Mode.deepValueOf(args[idx++].trim());
-        this.threads = Optional.of(args[idx++], INTEGER_UNMARSHALLER);
-        this.threadGroups = Utils.unmarshalIntArray(args[idx++]);
-        this.threadGroupLabels = Optional.of(args[idx++], STRING_COLLECTION_UNMARSHALLER);
-        this.warmupIterations = Optional.of(args[idx++], INTEGER_UNMARSHALLER);
-        this.warmupTime = Optional.of(args[idx++], TIME_VALUE_UNMARSHALLER);
-        this.warmupBatchSize = Optional.of(args[idx++], INTEGER_UNMARSHALLER);
-        this.measurementIterations = Optional.of(args[idx++], INTEGER_UNMARSHALLER);
-        this.measurementTime = Optional.of(args[idx++], TIME_VALUE_UNMARSHALLER);
-        this.measurementBatchSize = Optional.of(args[idx++], INTEGER_UNMARSHALLER);
-        this.forks = Optional.of(args[idx++], INTEGER_UNMARSHALLER);
-        this.warmupForks = Optional.of(args[idx++], INTEGER_UNMARSHALLER);
-        this.jvm = Optional.of(args[idx++], STRING_UNMARSHALLER);
-        this.jvmArgs = Optional.of(args[idx++], STRING_COLLECTION_UNMARSHALLER);
-        this.jvmArgsPrepend = Optional.of(args[idx++], STRING_COLLECTION_UNMARSHALLER);
-        this.jvmArgsAppend = Optional.of(args[idx++], STRING_COLLECTION_UNMARSHALLER);
-        this.params = Optional.of(args[idx++], PARAM_COLLECTION_UNMARSHALLER);
-        this.tu = Optional.of(args[idx++], TIMEUNIT_UNMARSHALLER);
-        this.opsPerInvocation = Optional.of(args[idx++], INTEGER_UNMARSHALLER);
-        this.timeout = Optional.of(args[idx++], TIME_VALUE_UNMARSHALLER);
+        this.userClassQName         = reader.nextString();
+        this.generatedClassQName    = reader.nextString();
+        this.method                 = reader.nextString();
+        this.mode                   = Mode.deepValueOf(reader.nextString());
+        this.threads                = reader.nextOptionalInt();
+        this.threadGroups           = reader.nextIntArray();
+        this.threadGroupLabels      = reader.nextOptionalStringCollection();
+        this.warmupIterations       = reader.nextOptionalInt();
+        this.warmupTime             = reader.nextOptionalTimeValue();
+        this.warmupBatchSize        = reader.nextOptionalInt();
+        this.measurementIterations  = reader.nextOptionalInt();
+        this.measurementTime        = reader.nextOptionalTimeValue();
+        this.measurementBatchSize   = reader.nextOptionalInt();
+        this.forks                  = reader.nextOptionalInt();
+        this.warmupForks            = reader.nextOptionalInt();
+        this.jvm                    = reader.nextOptionalString();
+        this.jvmArgs                = reader.nextOptionalStringCollection();
+        this.jvmArgsPrepend         = reader.nextOptionalStringCollection();
+        this.jvmArgsAppend          = reader.nextOptionalStringCollection();
+        this.params                 = reader.nextOptionalParamCollection();
+        this.tu                     = reader.nextOptionalTimeUnit();
+        this.opsPerInvocation       = reader.nextOptionalInt();
+        this.timeout                = reader.nextOptionalTimeValue();
     }
 
     public String toLine() {
-        return userClassQName + BR_SEPARATOR + generatedClassQName + BR_SEPARATOR + method + BR_SEPARATOR + mode + BR_SEPARATOR +
-                threads + BR_SEPARATOR + Utils.marshalIntArray(threadGroups) + BR_SEPARATOR + threadGroupLabels.toString(STRING_COLLECTION_MARSHALLER) + BR_SEPARATOR +
-                warmupIterations + BR_SEPARATOR + warmupTime + BR_SEPARATOR + warmupBatchSize + BR_SEPARATOR +
-                measurementIterations + BR_SEPARATOR + measurementTime + BR_SEPARATOR + measurementBatchSize + BR_SEPARATOR +
-                forks + BR_SEPARATOR + warmupForks + BR_SEPARATOR +
-                jvm.toString(STRING_MARSHALLER) + BR_SEPARATOR +
-                jvmArgs.toString(STRING_COLLECTION_MARSHALLER) + BR_SEPARATOR +
-                jvmArgsPrepend.toString(STRING_COLLECTION_MARSHALLER) + BR_SEPARATOR +
-                jvmArgsAppend.toString(STRING_COLLECTION_MARSHALLER) + BR_SEPARATOR +
-                params.toString(PARAM_COLLECTION_MARSHALLER) + BR_SEPARATOR + tu.toString(TIMEUNIT_MARSHALLER) + BR_SEPARATOR +
-                opsPerInvocation + BR_SEPARATOR +
-                timeout;
+        TestLineWriter writer = new TestLineWriter();
+
+        writer.putString(userClassQName);
+        writer.putString(generatedClassQName);
+        writer.putString(method);
+        writer.putString(mode.toString());
+        writer.putOptionalInt(threads);
+        writer.putIntArray(threadGroups);
+        writer.putOptionalStringCollection(threadGroupLabels);
+        writer.putOptionalInt(warmupIterations);
+        writer.putOptionalTimeValue(warmupTime);
+        writer.putOptionalInt(warmupBatchSize);
+        writer.putOptionalInt(measurementIterations);
+        writer.putOptionalTimeValue(measurementTime);
+        writer.putOptionalInt(measurementBatchSize);
+        writer.putOptionalInt(forks);
+        writer.putOptionalInt(warmupForks);
+        writer.putOptionalString(jvm);
+        writer.putOptionalStringCollection(jvmArgs);
+        writer.putOptionalStringCollection(jvmArgsPrepend);
+        writer.putOptionalStringCollection(jvmArgsAppend);
+        writer.putOptionalParamCollection(params);
+        writer.putOptionalTimeUnit(tu);
+        writer.putOptionalInt(opsPerInvocation);
+        writer.putOptionalTimeValue(timeout);
+
+        return writer.toString();
     }
 
     public BenchmarkListEntry cloneWith(Mode mode) {
@@ -317,111 +329,4 @@
         return timeout;
     }
 
-    static final Optional.Unmarshaller<Integer> INTEGER_UNMARSHALLER = new Optional.Unmarshaller<Integer>() {
-        @Override
-        public Integer valueOf(String s) {
-            return Integer.valueOf(s);
-        }
-    };
-
-    static final Optional.Unmarshaller<TimeValue> TIME_VALUE_UNMARSHALLER = new Optional.Unmarshaller<TimeValue>() {
-        @Override
-        public TimeValue valueOf(String s) {
-            return TimeValue.fromString(s);
-        }
-    };
-
-    static final Optional.Unmarshaller<TimeUnit> TIMEUNIT_UNMARSHALLER = new Optional.Unmarshaller<TimeUnit>() {
-        @Override
-        public TimeUnit valueOf(String s) {
-            return TimeUnit.valueOf(s);
-        }
-    };
-
-    static final Optional.Marshaller<TimeUnit> TIMEUNIT_MARSHALLER = new Optional.Marshaller<TimeUnit>() {
-        @Override
-        public String valueOf(TimeUnit val) {
-            return val.toString();
-        }
-    };
-
-    static final Optional.Unmarshaller<String> STRING_UNMARSHALLER = new Optional.Unmarshaller<String>() {
-        @Override
-        public String valueOf(String s) {
-            return s;
-        }
-    };
-
-    static final Optional.Marshaller<String> STRING_MARSHALLER = new Optional.Marshaller<String>() {
-        @Override
-        public String valueOf(String s) {
-            return s;
-        }
-    };
-
-    static final Optional.Unmarshaller<Collection<String>> STRING_COLLECTION_UNMARSHALLER = new Optional.Unmarshaller<Collection<String>>() {
-        @Override
-        public Collection<String> valueOf(String s) {
-            return Arrays.asList(s.split("===SEP==="));
-        }
-    };
-
-    static final Optional.Marshaller<Collection<String>> STRING_COLLECTION_MARSHALLER = new Optional.Marshaller<Collection<String>>() {
-        @Override
-        public String valueOf(Collection<String> src) {
-            StringBuilder sb = new StringBuilder();
-            for (String s : src) {
-                sb.append(s).append("===SEP===");
-            }
-            return sb.toString();
-        }
-    };
-
-    static final Optional.Unmarshaller<Map<String, String[]>> PARAM_COLLECTION_UNMARSHALLER = new Optional.Unmarshaller<Map<String, String[]>>() {
-        @Override
-        public Map<String, String[]> valueOf(String s) {
-            Map<String, String[]> map = new TreeMap<String, String[]>();
-            String[] pairs = s.split("===PAIR-SEP===");
-            for (String pair : pairs) {
-                String[] kv = pair.split("===SEP-K===");
-                if (kv[1].equalsIgnoreCase("===EMPTY===")) {
-                    map.put(kv[0], new String[0]);
-                } else {
-                    String[] vals = kv[1].split("===SEP-V===");
-                    for (int c = 0; c < vals.length; c++) {
-                        if (vals[c].equals("===EMPTY-VAL===")) {
-                            vals[c] = "";
-                        }
-                    }
-                    map.put(kv[0], vals);
-                }
-            }
-            return map;
-        }
-    };
-
-    static final Optional.Marshaller<Map<String, String[]>> PARAM_COLLECTION_MARSHALLER = new Optional.Marshaller<Map<String, String[]>>() {
-        @Override
-        public String valueOf(Map<String, String[]> src) {
-            StringBuilder sb = new StringBuilder();
-            for (Map.Entry<String, String[]> e : src.entrySet()) {
-                sb.append(e.getKey());
-                sb.append("===SEP-K===");
-                if (e.getValue().length == 0) {
-                    sb.append("===EMPTY===");
-                } else {
-                    for (String v : e.getValue()) {
-                        if (v.isEmpty()) {
-                            sb.append("===EMPTY-VAL===");
-                        } else {
-                            sb.append(v);
-                        }
-                        sb.append("===SEP-V===");
-                    }
-                }
-                sb.append("===PAIR-SEP===");
-            }
-            return sb.toString();
-        }
-    };
 }
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/CompilerHints.java	Wed Jul 13 19:31:07 2016 +0300
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/CompilerHints.java	Wed Jul 13 19:35:00 2016 +0300
@@ -85,7 +85,7 @@
     }
 
     private CompilerHints(String file, String resource) {
-        super(file, resource);
+        super(file, resource, null);
         hints = Collections.unmodifiableSet(read());
     }
 
--- a/jmh-core/src/main/java/org/openjdk/jmh/util/Optional.java	Wed Jul 13 19:31:07 2016 +0300
+++ b/jmh-core/src/main/java/org/openjdk/jmh/util/Optional.java	Wed Jul 13 19:35:00 2016 +0300
@@ -73,21 +73,6 @@
         return new Optional<T>(val);
     }
 
-    /**
-     * Parse the existing string value into the Option
-     * @param source source string
-     * @param unmarshaller unmarshaller lambda parsing the (String -&gt; T)
-     * @param <T> type
-     * @return value wrapped in the Option
-     */
-    public static <T> Optional<T> of(String source, Unmarshaller<T> unmarshaller) {
-        if (source.equals("[]")) {
-            return Optional.none();
-        } else {
-            return Optional.of(unmarshaller.valueOf(source.substring(1, source.length() - 1)));
-        }
-    }
-
     public static <T> Optional<T> eitherOf(T val) {
         if (val == null) {
             return Optional.none();
@@ -108,14 +93,6 @@
         }
     }
 
-    public String toString(Marshaller<T> m) {
-        if (val == null) {
-            return "[]";
-        } else {
-            return "[" + m.valueOf(val) + "]";
-        }
-    }
-
     public T get() {
         if (val == null) {
             throw new IllegalStateException("Optional is null");
@@ -140,12 +117,4 @@
         return val != null ? val.hashCode() : 0;
     }
 
-    public interface Unmarshaller<T> {
-        T valueOf(String s);
-    }
-
-    public interface Marshaller<T> {
-        String valueOf(T val);
-    }
-
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/util/lines/Constants.java	Wed Jul 13 19:35:00 2016 +0300
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2014, 2015, 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.util.lines;
+
+public class Constants {
+
+    public static final String MAGIC = "JMH ";
+
+    public static final char TAG_EMPTY_OPTIONAL     = 'E';
+    public static final char TAG_STRING             = 'S';
+    public static final char TAG_INT                = 'I';
+    public static final char TAG_TIMEVALUE          = 'T';
+    public static final char TAG_STRING_COLLECTION  = 'L';
+    public static final char TAG_INT_ARRAY          = 'A';
+    public static final char TAG_PARAM_MAP          = 'M';
+    public static final char TAG_TIMEUNIT           = 'U';
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/util/lines/TestLineReader.java	Wed Jul 13 19:35:00 2016 +0300
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2014, 2015, 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.util.lines;
+
+import org.openjdk.jmh.runner.options.TimeValue;
+import org.openjdk.jmh.util.Optional;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import static org.openjdk.jmh.util.lines.Constants.*;
+
+public class TestLineReader {
+
+    private final String line;
+    private final boolean correct;
+    private int cursor;
+
+    public TestLineReader(String line) {
+        this.line = line;
+        this.correct = (line.length() > MAGIC.length() && line.startsWith(MAGIC));
+        this.cursor = MAGIC.length();
+    }
+
+    private int readLen() {
+        StringBuilder sb = new StringBuilder();
+        char c = line.charAt(cursor);
+        while (Character.isDigit(c)) {
+            sb.append(c);
+            cursor++;
+            c = line.charAt(cursor);
+        }
+        cursor++;
+        return Integer.valueOf(sb.toString());
+    }
+
+    private String readString() {
+        int len = readLen();
+        String s = line.substring(cursor, cursor + len);
+        cursor += len + 1;
+        return s;
+    }
+
+    private char readChar() {
+        char c = line.charAt(cursor);
+        cursor += 2;
+        return c;
+    }
+
+    public String nextString() {
+        char tag = readChar();
+        if (tag == TAG_STRING) {
+            return readString();
+        } else {
+            throw error("unexpected tag = " + tag);
+        }
+    }
+
+    private RuntimeException error(String msg) {
+        return new IllegalStateException("Error: " + msg + "\n at \"" + line + "\", pos " + cursor);
+    }
+
+    public boolean isCorrect() {
+        return correct;
+    }
+
+    public Optional<Integer> nextOptionalInt() {
+        char tag = readChar();
+        if (tag == Constants.TAG_EMPTY_OPTIONAL) {
+            return Optional.none();
+        } else if (tag == TAG_INT) {
+            return Optional.of(Integer.valueOf(readString()));
+        } else {
+            throw error("unexpected tag = " + tag);
+        }
+    }
+
+    public Optional<String> nextOptionalString() {
+        char tag = readChar();
+        if (tag == Constants.TAG_EMPTY_OPTIONAL) {
+            return Optional.none();
+        } else if (tag == TAG_STRING) {
+            return Optional.of(readString());
+        } else {
+            throw error("unexpected tag = " + tag);
+        }
+    }
+
+    public Optional<TimeValue> nextOptionalTimeValue() {
+        char tag = readChar();
+        if (tag == Constants.TAG_EMPTY_OPTIONAL) {
+            return Optional.none();
+        } else if (tag == TAG_TIMEVALUE) {
+            return Optional.of(TimeValue.fromString(readString()));
+        } else {
+            throw error("unexpected tag = " + tag);
+        }
+    }
+
+    public Optional<TimeUnit> nextOptionalTimeUnit() {
+        char tag = readChar();
+        if (tag == Constants.TAG_EMPTY_OPTIONAL) {
+            return Optional.none();
+        } else if (tag == TAG_TIMEUNIT) {
+            return Optional.of(TimeUnit.valueOf(readString()));
+        } else {
+            throw error("unexpected tag = " + tag);
+        }
+    }
+
+    public Optional<Collection<String>> nextOptionalStringCollection() {
+        char tag = readChar();
+        if (tag == Constants.TAG_EMPTY_OPTIONAL) {
+            return Optional.none();
+        } else if (tag == TAG_STRING_COLLECTION) {
+            int len = readLen();
+            Collection<String> list = new ArrayList<String>();
+            for (int c = 0; c < len; c++) {
+                list.add(readString());
+            }
+            return Optional.of(list);
+        } else {
+            throw error("unexpected tag = " + tag);
+        }
+    }
+
+    public int[] nextIntArray() {
+        char tag = readChar();
+        if (tag == TAG_INT_ARRAY) {
+            int len = readLen();
+            int[] rs = new int[len];
+            for (int c = 0; c < len; c++) {
+                rs[c] = Integer.valueOf(readString());
+            }
+            return rs;
+        } else {
+            throw error("unexpected tag = " + tag);
+        }
+    }
+
+    public Optional<Map<String, String[]>> nextOptionalParamCollection() {
+        char tag = readChar();
+        if (tag == Constants.TAG_EMPTY_OPTIONAL) {
+            return Optional.none();
+        } else if (tag == TAG_PARAM_MAP) {
+            Map<String, String[]> result = new HashMap<String, String[]>();
+
+            int kvs = readLen();
+            for (int kv = 0; kv < kvs; kv++) {
+                String key = readString();
+
+                int vlen = readLen();
+                String[] values = new String[vlen];
+                for (int v = 0; v < vlen; v++) {
+                    values[v] = readString();
+                }
+
+                result.put(key, values);
+            }
+            return Optional.of(result);
+        } else {
+            throw error("unexpected tag = " + tag);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/util/lines/TestLineWriter.java	Wed Jul 13 19:35:00 2016 +0300
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2014, 2015, 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.util.lines;
+
+import org.openjdk.jmh.runner.options.TimeValue;
+import org.openjdk.jmh.util.Optional;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import static org.openjdk.jmh.util.lines.Constants.*;
+
+public class TestLineWriter {
+
+    private StringBuilder line;
+
+    public TestLineWriter() {
+        line = new StringBuilder();
+        line.append(MAGIC);
+    }
+
+    private void appendWithLen(String s) {
+        appendLen(s.length());
+        line.append(s);
+        line.append(" ");
+    }
+
+    private void appendLen(int len) {
+        line.append(len);
+        line.append(" ");
+    }
+
+    private void appendTag(char tag) {
+        line.append(tag);
+        line.append(" ");
+    }
+
+    public void putString(String s) {
+        appendTag(TAG_STRING);
+        appendWithLen(s);
+    }
+
+    public void putOptionalInt(Optional<Integer> opt) {
+        if (!opt.hasValue()) {
+            appendTag(TAG_EMPTY_OPTIONAL);
+        } else {
+            appendTag(TAG_INT);
+            appendWithLen(String.valueOf(opt.get()));
+        }
+    }
+
+    public void putOptionalString(Optional<String> opt) {
+        if (!opt.hasValue()) {
+            appendTag(TAG_EMPTY_OPTIONAL);
+        } else {
+            appendTag(TAG_STRING);
+            appendWithLen(opt.get());
+        }
+    }
+
+    public void putIntArray(int[] arr) {
+        appendTag(TAG_INT_ARRAY);
+        appendLen(arr.length);
+        for (int v : arr) {
+            appendWithLen(String.valueOf(v));
+        }
+    }
+
+    public void putOptionalStringCollection(Optional<Collection<String>> opt) {
+        if (!opt.hasValue()) {
+            appendTag(TAG_EMPTY_OPTIONAL);
+        } else {
+            appendTag(TAG_STRING_COLLECTION);
+            Collection<String> coll = opt.get();
+            appendLen(coll.size());
+            for (String s : coll) {
+                appendWithLen(s);
+            }
+        }
+    }
+
+    public void putOptionalTimeValue(Optional<TimeValue> opt) {
+        if (!opt.hasValue()) {
+            appendTag(TAG_EMPTY_OPTIONAL);
+        } else {
+            appendTag(TAG_TIMEVALUE);
+            appendWithLen(opt.get().toString());
+        }
+    }
+
+    public void putOptionalTimeUnit(Optional<TimeUnit> opt) {
+        if (!opt.hasValue()) {
+            appendTag(TAG_EMPTY_OPTIONAL);
+        } else {
+            appendTag(TAG_TIMEUNIT);
+            appendWithLen(opt.get().toString());
+        }
+    }
+
+    public void putOptionalParamCollection(Optional<Map<String, String[]>> opt) {
+        if (!opt.hasValue()) {
+            appendTag(TAG_EMPTY_OPTIONAL);
+        } else {
+            appendTag(TAG_PARAM_MAP);
+
+            Map<String, String[]> map = opt.get();
+            appendLen(map.size());
+
+            for (String key : map.keySet()) {
+                appendWithLen(key);
+
+                String[] vals = map.get(key);
+                appendLen(vals.length);
+
+                for (String value : vals) {
+                    appendWithLen(value);
+                }
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        return line.toString();
+    }
+
+}
--- a/jmh-core/src/test/java/org/openjdk/jmh/runner/TestBenchmarkList.java	Wed Jul 13 19:31:07 2016 +0300
+++ b/jmh-core/src/test/java/org/openjdk/jmh/runner/TestBenchmarkList.java	Wed Jul 13 19:35:00 2016 +0300
@@ -26,14 +26,15 @@
 
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.openjdk.jmh.annotations.Mode;
 import org.openjdk.jmh.runner.format.OutputFormat;
 import org.openjdk.jmh.runner.format.OutputFormatFactory;
+import org.openjdk.jmh.runner.options.TimeValue;
 import org.openjdk.jmh.runner.options.VerboseMode;
+import org.openjdk.jmh.util.Optional;
 
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -46,9 +47,162 @@
     private static BenchmarkList list;
     private static OutputFormat out;
 
+    private static void stub(StringBuilder sb, String userClassQName, String generatedClassQName, String method, Mode mode) {
+        BenchmarkListEntry br = new BenchmarkListEntry(
+                userClassQName,
+                generatedClassQName,
+                method,
+                mode,
+                Optional.<Integer>none(),
+                new int[]{1},
+                Optional.<Collection<String>>none(),
+                Optional.<Integer>none(),
+                Optional.<TimeValue>none(),
+                Optional.<Integer>none(),
+                Optional.<Integer>none(),
+                Optional.<TimeValue>none(),
+                Optional.<Integer>none(),
+                Optional.<Integer>none(),
+                Optional.<Integer>none(),
+                Optional.<String>none(),
+                Optional.<Collection<String>>none(),
+                Optional.<Collection<String>>none(),
+                Optional.<Collection<String>>none(),
+                Optional.<Map<String, String[]>>none(),
+                Optional.<TimeUnit>none(),
+                Optional.<Integer>none(),
+                Optional.<TimeValue>none()
+        );
+
+        sb.append(br.toLine());
+        sb.append(String.format("%n"));
+    }
+
     @BeforeClass
     public static void setUpClass() throws Exception {
-        list = BenchmarkList.fromResource("/org/openjdk/jmh/runner/MicroBenchmarks");
+        StringBuilder sb = new StringBuilder();
+
+        stub(sb,
+                "oracle.micro.benchmarks.api.java.util.concurrent.NormalMaps",
+                "oracle.micro.benchmarks.api.java.util.concurrent.generated.NormalMaps",
+                "testConcurrentHashMap",
+                Mode.AverageTime);
+
+        stub(sb,
+                "oracle.micro.benchmarks.app.jbb05.GeneratedSPECjbb2005HashMap",
+                "oracle.micro.benchmarks.app.jbb05.generated.GeneratedSPECjbb2005HashMap",
+                "jbb2005HashMapGetIntThroughput",
+                Mode.AverageTime);
+
+        stub(sb,
+                "oracle.micro.benchmarks.app.jbb05.GeneratedSPECjbb2005HashMap",
+                "oracle.micro.benchmarks.app.jbb05.generated.GeneratedSPECjbb2005HashMap",
+                "jbb2005HashMapGetIntGCThroughput",
+                Mode.AverageTime);
+
+        stub(sb,
+                "oracle.micro.benchmarks.app.jbb05.GeneratedSPECjbb2005HashMap",
+                "oracle.micro.benchmarks.app.jbb05.generated.GeneratedSPECjbb2005HashMap",
+                "jbb2005HashMapGetIntegerThroughput",
+                Mode.AverageTime);
+
+        stub(sb,
+                "oracle.micro.benchmarks.app.jbb05.GeneratedSPECjbb2005HashMap",
+                "oracle.micro.benchmarks.app.jbb05.generated.GeneratedSPECjbb2005HashMap",
+                "jbb2005ResizedHashMapGetIntThroughput",
+                Mode.AverageTime);
+
+        stub(sb,
+                "oracle.micro.benchmarks.app.jbb05.GeneratedSPECjbb2005HashMap",
+                "oracle.micro.benchmarks.app.jbb05.generated.GeneratedSPECjbb2005HashMap",
+                "jbb2005ResizedHashMapGetIntegerThroughput",
+                Mode.AverageTime);
+
+        stub(sb,
+                "oracle.micro.benchmarks.app.sjent.GeneratedPrintBase64",
+                "oracle.micro.benchmarks.app.sjent.generated.GeneratedPrintBase64",
+                "printBase64Binary_128bytesThroughput",
+                Mode.AverageTime);
+
+        stub(sb,
+                "oracle.micro.benchmarks.app.sjent.GeneratedPrintBase64",
+                "oracle.micro.benchmarks.app.sjent.generated.GeneratedPrintBase64",
+                "printBase64Binary_32bytesThroughput",
+                Mode.AverageTime);
+
+        stub(sb,
+                "oracle.micro.benchmarks.app.sjent.GeneratedPrintBase64",
+                "oracle.micro.benchmarks.app.sjent.generated.GeneratedPrintBase64",
+                "printBase64Binary_512bytesThroughput",
+                Mode.AverageTime);
+
+        stub(sb,
+                "oracle.micro.benchmarks.api.java.util.concurrent.GeneratedMaps",
+                "oracle.micro.benchmarks.api.java.util.concurrent.generated.GeneratedMaps",
+                "testConcurrentHashMap",
+                Mode.AverageTime);
+
+        stub(sb,
+                "org.openjdk.jmh.runner.TestMicro",
+                "org.openjdk.jmh.runner.generated.TestMicro",
+                "dummy",
+                Mode.AverageTime);
+
+        stub(sb,
+                "org.openjdk.jmh.runner.TestMicro",
+                "org.openjdk.jmh.runner.generated.TestMicro",
+                "dummyWarmThroughput",
+                Mode.AverageTime);
+
+        stub(sb,
+                "org.openjdk.jmh.runner.TestMicro",
+                "org.openjdk.jmh.runner.generated.TestMicro",
+                "dummyWarmOnlyThroughput",
+                Mode.AverageTime);
+
+        stub(sb,
+                "org.openjdk.jmh.runner.TestMicro",
+                "org.openjdk.jmh.runner.generated.TestMicro",
+                "dummySetupPayloadThroughput",
+                Mode.AverageTime);
+
+        stub(sb,
+                "org.openjdk.jmh.runner.TestMicro",
+                "org.openjdk.jmh.runner.generated.TestMicro",
+                "boom_ExceptionThroughput",
+                Mode.AverageTime);
+
+        stub(sb,
+                "org.openjdk.jmh.runner.TestMicro",
+                "org.openjdk.jmh.runner.generated.TestMicro",
+                "boom_ErrorThroughput",
+                Mode.AverageTime);
+
+        stub(sb,
+                "org.openjdk.jmh.runner.TestMicro",
+                "org.openjdk.jmh.runner.generated.TestMicro",
+                "boom_ThrowableThroughput",
+                Mode.AverageTime);
+
+        stub(sb,
+                "org.openjdk.jmh.runner.TestMicro",
+                "org.openjdk.jmh.runner.generated.TestMicro",
+                "blackholedThroughput",
+                Mode.AverageTime);
+
+        stub(sb,
+                "org.openjdk.jmh.runner.TestBrokenMicro",
+                "org.openjdk.jmh.runner.generated.TestBrokenMicro",
+                "dummyPayloadThroughput",
+                Mode.AverageTime);
+
+        stub(sb,
+                "org.openjdk.jmh.runner.TestExceptionThrowingMicro",
+                "org.openjdk.jmh.runner.generated.TestExceptionThrowingMicro",
+                "ouchThroughput",
+                Mode.AverageTime);
+
+        list = BenchmarkList.fromString(sb.toString());
         out = OutputFormatFactory.createFormatInstance(System.out, VerboseMode.NORMAL);
     }
 
--- a/jmh-core/src/test/java/org/openjdk/jmh/util/TestFileUtils.java	Wed Jul 13 19:31:07 2016 +0300
+++ b/jmh-core/src/test/java/org/openjdk/jmh/util/TestFileUtils.java	Wed Jul 13 19:35:00 2016 +0300
@@ -37,7 +37,7 @@
 
     @Test
     public void testExtractFromResource() throws Exception {
-        File test = FileUtils.extractFromResource("/org/openjdk/jmh/runner/MicroBenchmarks");
+        File test = FileUtils.extractFromResource("/org/openjdk/jmh/results/format/output-golden.json");
         test.deleteOnExit();
         assertTrue(test.exists());
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/test/java/org/openjdk/jmh/util/TestLineTest.java	Wed Jul 13 19:35:00 2016 +0300
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2014, 2015, 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.util;
+
+import junit.framework.Assert;
+import org.junit.Test;
+import org.openjdk.jmh.runner.options.TimeValue;
+import org.openjdk.jmh.util.lines.TestLineReader;
+import org.openjdk.jmh.util.lines.TestLineWriter;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+public class TestLineTest {
+
+    @Test
+    public void test() {
+        TestLineWriter writer = new TestLineWriter();
+
+        writer.putString("jmh");
+        writer.putString("test");
+        writer.putOptionalString(Optional.eitherOf("full-optional"));
+        writer.putOptionalString(Optional.<String>none());
+
+        writer.putOptionalInt(Optional.eitherOf(42));
+        writer.putOptionalInt(Optional.<Integer>none());
+
+        writer.putIntArray(new int[] {5, 3, 2});
+
+        writer.putOptionalTimeValue(Optional.eitherOf(TimeValue.milliseconds(14)));
+        writer.putOptionalTimeValue(Optional.<TimeValue>none());
+
+        writer.putOptionalTimeUnit(Optional.eitherOf(TimeUnit.HOURS));
+        writer.putOptionalTimeUnit(Optional.<TimeUnit>none());
+
+        writer.putOptionalStringCollection(Optional.<Collection<String>>eitherOf(Arrays.asList("foo", "bar", "baz")));
+        writer.putOptionalStringCollection(Optional.<Collection<String>>none());
+
+        HashMap<String, String[]> expectedMap = new HashMap<String, String[]>();
+        expectedMap.put("key1", new String[] {"val1", "val2"});
+        expectedMap.put("key2", new String[] {"val3", "val4"});
+        writer.putOptionalParamCollection(Optional.<Map<String,String[]>>eitherOf(expectedMap));
+        writer.putOptionalParamCollection(Optional.<Map<String,String[]>>none());
+
+        String s = writer.toString();
+
+        TestLineReader reader = new TestLineReader(s);
+
+        Assert.assertEquals("jmh", reader.nextString());
+        Assert.assertEquals("test", reader.nextString());
+
+        Assert.assertEquals("full-optional", reader.nextOptionalString().get());
+        Assert.assertEquals(false, reader.nextOptionalString().hasValue());
+
+        Assert.assertEquals(42, (int)reader.nextOptionalInt().get());
+        Assert.assertEquals(false, reader.nextOptionalInt().hasValue());
+
+        Assert.assertTrue(Arrays.equals(new int[] {5, 3, 2}, reader.nextIntArray()));
+
+        Assert.assertEquals(TimeValue.milliseconds(14), reader.nextOptionalTimeValue().get());
+        Assert.assertEquals(false, reader.nextOptionalTimeValue().hasValue());
+
+        Assert.assertEquals(TimeUnit.HOURS, reader.nextOptionalTimeUnit().get());
+        Assert.assertEquals(false, reader.nextOptionalTimeUnit().hasValue());
+
+        Assert.assertEquals(Arrays.asList("foo", "bar", "baz"), reader.nextOptionalStringCollection().get());
+        Assert.assertEquals(false, reader.nextOptionalStringCollection().hasValue());
+
+        Map<String, String[]> actualMap = reader.nextOptionalParamCollection().get();
+        Assert.assertEquals(expectedMap.size(), actualMap.size());
+        Assert.assertEquals(expectedMap.keySet(), actualMap.keySet());
+
+        for (String key : expectedMap.keySet()) {
+            String[] expectedVals = expectedMap.get(key);
+            String[] actualVals = actualMap.get(key);
+            Assert.assertTrue(Arrays.equals(expectedVals, actualVals));
+        }
+    }
+
+}
--- a/jmh-core/src/test/resources/org/openjdk/jmh/runner/MicroBenchmarks	Wed Jul 13 19:31:07 2016 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-#    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.
-#
-
-
-oracle.micro.benchmarks.api.java.util.concurrent.NormalMaps===,===oracle.micro.benchmarks.api.java.util.concurrent.generated.NormalMaps===,===testConcurrentHashMap===,===AverageTime===,===[4]===,===1====,===[]===,===[5]===,===[1 s]===,===[]===,===[5]===,===[4 s]===,===[]===,===[1]===,===[]===,===[]===,===[]===,===[]===,===[]===,===[prefixLen===SEP-K===0===SEP-V===10===SEP-V===100===SEP-V======PAIR-SEP===]===,===[NANOSECONDS]===,===[]===,===[10 min]
-oracle.micro.benchmarks.app.jbb05.GeneratedSPECjbb2005HashMap===,===oracle.micro.benchmarks.app.jbb05.generated.GeneratedSPECjbb2005HashMap===,===jbb2005HashMapGetIntThroughput===,===AverageTime===,===[4]===,===1====,===[]===,===[5]===,===[1 s]===,===[]===,===[5]===,===[4 s]===,===[]===,===[1]===,===[]===,===[]===,===[]===,===[]===,===[]===,===[prefixLen===SEP-K===0===SEP-V===10===SEP-V===100===SEP-V======PAIR-SEP===]===,===[NANOSECONDS]===,===[]===,===[10 min]
-oracle.micro.benchmarks.app.jbb05.GeneratedSPECjbb2005HashMap===,===oracle.micro.benchmarks.app.jbb05.generated.GeneratedSPECjbb2005HashMap===,===jbb2005HashMapGetIntGCThroughput===,===AverageTime===,===[4]===,===1====,===[]===,===[5]===,===[1 s]===,===[]===,===[5]===,===[4 s]===,===[]===,===[1]===,===[]===,===[]===,===[]===,===[]===,===[]===,===[prefixLen===SEP-K===0===SEP-V===10===SEP-V===100===SEP-V======PAIR-SEP===]===,===[NANOSECONDS]===,===[]===,===[10 min]
-oracle.micro.benchmarks.app.jbb05.GeneratedSPECjbb2005HashMap===,===oracle.micro.benchmarks.app.jbb05.generated.GeneratedSPECjbb2005HashMap===,===jbb2005HashMapGetIntegerThroughput===,===AverageTime===,===[4]===,===1====,===[]===,===[5]===,===[1 s]===,===[]===,===[5]===,===[4 s]===,===[]===,===[1]===,===[]===,===[]===,===[]===,===[]===,===[]===,===[prefixLen===SEP-K===0===SEP-V===10===SEP-V===100===SEP-V======PAIR-SEP===]===,===[NANOSECONDS]===,===[]===,===[10 min]
-oracle.micro.benchmarks.app.jbb05.GeneratedSPECjbb2005HashMap===,===oracle.micro.benchmarks.app.jbb05.generated.GeneratedSPECjbb2005HashMap===,===jbb2005ResizedHashMapGetIntThroughput===,===AverageTime===,===[4]===,===1====,===[]===,===[5]===,===[1 s]===,===[]===,===[5]===,===[4 s]===,===[]===,===[1]===,===[]===,===[]===,===[]===,===[]===,===[]===,===[prefixLen===SEP-K===0===SEP-V===10===SEP-V===100===SEP-V======PAIR-SEP===]===,===[NANOSECONDS]===,===[]===,===[10 min]
-oracle.micro.benchmarks.app.jbb05.GeneratedSPECjbb2005HashMap===,===oracle.micro.benchmarks.app.jbb05.generated.GeneratedSPECjbb2005HashMap===,===jbb2005ResizedHashMapGetIntegerThroughput===,===AverageTime===,===[4]===,===1====,===[]===,===[5]===,===[1 s]===,===[]===,===[5]===,===[4 s]===,===[]===,===[1]===,===[]===,===[]===,===[]===,===[]===,===[]===,===[prefixLen===SEP-K===0===SEP-V===10===SEP-V===100===SEP-V======PAIR-SEP===]===,===[NANOSECONDS]===,===[]===,===[10 min]
-oracle.micro.benchmarks.app.sjent.GeneratedPrintBase64===,===oracle.micro.benchmarks.app.sjent.generated.GeneratedPrintBase64===,===printBase64Binary_128bytesThroughput===,===AverageTime===,===[4]===,===1====,===[]===,===[5]===,===[1 s]===,===[]===,===[5]===,===[4 s]===,===[]===,===[1]===,===[]===,===[]===,===[]===,===[]===,===[]===,===[prefixLen===SEP-K===0===SEP-V===10===SEP-V===100===SEP-V======PAIR-SEP===]===,===[NANOSECONDS]===,===[]===,===[10 min]
-oracle.micro.benchmarks.app.sjent.GeneratedPrintBase64===,===oracle.micro.benchmarks.app.sjent.generated.GeneratedPrintBase64===,===printBase64Binary_32bytesThroughput===,===AverageTime===,===[4]===,===1====,===[]===,===[5]===,===[1 s]===,===[]===,===[5]===,===[4 s]===,===[]===,===[1]===,===[]===,===[]===,===[]===,===[]===,===[]===,===[prefixLen===SEP-K===0===SEP-V===10===SEP-V===100===SEP-V======PAIR-SEP===]===,===[NANOSECONDS]===,===[]===,===[10 min]
-oracle.micro.benchmarks.app.sjent.GeneratedPrintBase64===,===oracle.micro.benchmarks.app.sjent.generated.GeneratedPrintBase64===,===printBase64Binary_512bytesThroughput===,===AverageTime===,===[4]===,===1====,===[]===,===[5]===,===[1 s]===,===[]===,===[5]===,===[4 s]===,===[]===,===[1]===,===[]===,===[]===,===[]===,===[]===,===[]===,===[prefixLen===SEP-K===0===SEP-V===10===SEP-V===100===SEP-V======PAIR-SEP===]===,===[NANOSECONDS]===,===[]===,===[10 min]
-oracle.micro.benchmarks.api.java.util.concurrent.GeneratedMaps===,===oracle.micro.benchmarks.api.java.util.concurrent.generated.GeneratedMaps===,===testConcurrentHashMap===,===AverageTime===,===[4]===,===1====,===[]===,===[5]===,===[1 s]===,===[]===,===[5]===,===[4 s]===,===[]===,===[1]===,===[]===,===[]===,===[]===,===[]===,===[]===,===[prefixLen===SEP-K===0===SEP-V===10===SEP-V===100===SEP-V======PAIR-SEP===]===,===[NANOSECONDS]===,===[]===,===[10 min]
-
-org.openjdk.jmh.runner.TestMicro===,===org.openjdk.jmh.runner.generated.TestMicro===,===dummy===,===AverageTime===,===[4]===,===1====,===[]===,===[5]===,===[1 s]===,===[]===,===[5]===,===[4 s]===,===[]===,===[1]===,===[]===,===[]===,===[]===,===[]===,===[]===,===[prefixLen===SEP-K===0===SEP-V===10===SEP-V===100===SEP-V======PAIR-SEP===]===,===[NANOSECONDS]===,===[]===,===[10 min]
-org.openjdk.jmh.runner.TestMicro===,===org.openjdk.jmh.runner.generated.TestMicro===,===dummyWarmThroughput===,===AverageTime===,===[4]===,===1====,===[]===,===[5]===,===[1 s]===,===[]===,===[5]===,===[4 s]===,===[]===,===[1]===,===[]===,===[]===,===[]===,===[]===,===[]===,===[prefixLen===SEP-K===0===SEP-V===10===SEP-V===100===SEP-V======PAIR-SEP===]===,===[NANOSECONDS]===,===[]===,===[10 min]
-org.openjdk.jmh.runner.TestMicro===,===org.openjdk.jmh.runner.generated.TestMicro===,===dummyWarmOnlyThroughput===,===AverageTime===,===[4]===,===1====,===[]===,===[5]===,===[1 s]===,===[]===,===[5]===,===[4 s]===,===[]===,===[1]===,===[]===,===[]===,===[]===,===[]===,===[]===,===[prefixLen===SEP-K===0===SEP-V===10===SEP-V===100===SEP-V======PAIR-SEP===]===,===[NANOSECONDS]===,===[]===,===[10 min]
-org.openjdk.jmh.runner.TestMicro===,===org.openjdk.jmh.runner.generated.TestMicro===,===dummySetupPayloadThroughput===,===AverageTime===,===[4]===,===1====,===[]===,===[5]===,===[1 s]===,===[]===,===[5]===,===[4 s]===,===[]===,===[1]===,===[]===,===[]===,===[]===,===[]===,===[]===,===[prefixLen===SEP-K===0===SEP-V===10===SEP-V===100===SEP-V======PAIR-SEP===]===,===[NANOSECONDS]===,===[]===,===[10 min]
-org.openjdk.jmh.runner.TestMicro===,===org.openjdk.jmh.runner.generated.TestMicro===,===boom_ExceptionThroughput===,===AverageTime===,===[4]===,===1====,===[]===,===[5]===,===[1 s]===,===[]===,===[5]===,===[4 s]===,===[]===,===[1]===,===[]===,===[]===,===[]===,===[]===,===[]===,===[prefixLen===SEP-K===0===SEP-V===10===SEP-V===100===SEP-V======PAIR-SEP===]===,===[NANOSECONDS]===,===[]===,===[10 min]
-org.openjdk.jmh.runner.TestMicro===,===org.openjdk.jmh.runner.generated.TestMicro===,===boom_ErrorThroughput===,===AverageTime===,===[4]===,===1====,===[]===,===[5]===,===[1 s]===,===[]===,===[5]===,===[4 s]===,===[]===,===[1]===,===[]===,===[]===,===[]===,===[]===,===[]===,===[prefixLen===SEP-K===0===SEP-V===10===SEP-V===100===SEP-V======PAIR-SEP===]===,===[NANOSECONDS]===,===[]===,===[10 min]
-org.openjdk.jmh.runner.TestMicro===,===org.openjdk.jmh.runner.generated.TestMicro===,===boom_ThrowableThroughput===,===AverageTime===,===[4]===,===1====,===[]===,===[5]===,===[1 s]===,===[]===,===[5]===,===[4 s]===,===[]===,===[1]===,===[]===,===[]===,===[]===,===[]===,===[]===,===[prefixLen===SEP-K===0===SEP-V===10===SEP-V===100===SEP-V======PAIR-SEP===]===,===[NANOSECONDS]===,===[]===,===[10 min]
-org.openjdk.jmh.runner.TestMicro===,===org.openjdk.jmh.runner.generated.TestMicro===,===blackholedThroughput===,===AverageTime===,===[4]===,===1====,===[]===,===[5]===,===[1 s]===,===[]===,===[5]===,===[4 s]===,===[]===,===[1]===,===[]===,===[]===,===[]===,===[]===,===[]===,===[prefixLen===SEP-K===0===SEP-V===10===SEP-V===100===SEP-V======PAIR-SEP===]===,===[NANOSECONDS]===,===[]===,===[10 min]
-org.openjdk.jmh.runner.TestBrokenMicro===,===org.openjdk.jmh.runner.generated.TestBrokenMicro===,===dummyPayloadThroughput===,===AverageTime===,===[4]===,===1====,===[]===,===[5]===,===[1 s]===,===[]===,===[5]===,===[4 s]===,===[]===,===[1]===,===[]===,===[]===,===[]===,===[]===,===[]===,===[prefixLen===SEP-K===0===SEP-V===10===SEP-V===100===SEP-V======PAIR-SEP===]===,===[NANOSECONDS]===,===[]===,===[10 min]
-org.openjdk.jmh.runner.TestExceptionThrowingMicro===,===org.openjdk.jmh.runner.generated.TestExceptionThrowingMicro===,===ouchThroughput===,===AverageTime===,===[4]===,===1====,===[]===,===[5]===,===[1 s]===,===[]===,===[5]===,===[4 s]===,===[]===,===[1]===,===[]===,===[]===,===[]===,===[]===,===[]===,===[prefixLen===SEP-K===0===SEP-V===10===SEP-V===100===SEP-V======PAIR-SEP===]===,===[NANOSECONDS]===,===[]===,===[10 min]