From 8afd353fc66fa3b87bfac36293baad6508d63f62 Mon Sep 17 00:00:00 2001 From: salyh Date: Mon, 14 Jul 2014 01:31:24 +0200 Subject: [PATCH 21/22] introduce jmh based fleece-benchmark suite Signed-off-by: salyh --- fleece-benchmark/pom.xml | 136 +++++++++++ .../fleece/core/jmh/benchmark/BenchmarkMain.java | 85 +++++++ .../core/jmh/benchmark/BenchmarkStreamParser.java | 270 +++++++++++++++++++++ .../apache/fleece/core/jmh/benchmark/Buffers.java | 72 ++++++ .../core/jmh/benchmark/CreateJsonTestFiles.java | 144 +++++++++++ 5 files changed, 707 insertions(+) create mode 100644 fleece-benchmark/pom.xml create mode 100644 fleece-benchmark/src/test/java/org/apache/fleece/core/jmh/benchmark/BenchmarkMain.java create mode 100644 fleece-benchmark/src/test/java/org/apache/fleece/core/jmh/benchmark/BenchmarkStreamParser.java create mode 100644 fleece-benchmark/src/test/java/org/apache/fleece/core/jmh/benchmark/Buffers.java create mode 100644 fleece-benchmark/src/test/java/org/apache/fleece/core/jmh/benchmark/CreateJsonTestFiles.java diff --git a/fleece-benchmark/pom.xml b/fleece-benchmark/pom.xml new file mode 100644 index 0000000..d7e1a87 --- /dev/null +++ b/fleece-benchmark/pom.xml @@ -0,0 +1,136 @@ + + + + + fleece + org.apache.fleece + 1.0-SNAPSHOT + + 4.0.0 + + fleece-benchmark + Fleece :: Benchmark + + + ${project.parent.reporting.outputDirectory} + 0.9.3 + + + + + + org.apache.fleece + fleece-core + ${project.version} + test + + + + org.apache.fleece + fleece-jaxrs + ${project.version} + test + + + + org.apache.fleece + fleece-mapper + ${project.version} + test + + + + org.openjdk.jmh + jmh-core + ${jmh.version} + test + + + org.openjdk.jmh + jmh-generator-annprocess + ${jmh.version} + test + + + commons-io + commons-io + 2.4 + test + + + + + + + false + src/test/resources + + **/* + + + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + 1.3.1 + + + enforce-versions + + enforce + + + + + 1.7.0 + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.7 + 1.7 + UTF-8 + true + true + + + + + org.codehaus.mojo + exec-maven-plugin + 1.3.1 + + test + java + + -classpath + + org.apache.fleece.core.jmh.benchmark.BenchmarkMain + .* + + + + + + diff --git a/fleece-benchmark/src/test/java/org/apache/fleece/core/jmh/benchmark/BenchmarkMain.java b/fleece-benchmark/src/test/java/org/apache/fleece/core/jmh/benchmark/BenchmarkMain.java new file mode 100644 index 0000000..9754bc1 --- /dev/null +++ b/fleece-benchmark/src/test/java/org/apache/fleece/core/jmh/benchmark/BenchmarkMain.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fleece.core.jmh.benchmark; + +import java.util.concurrent.TimeUnit; + +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.results.format.ResultFormatType; +import org.openjdk.jmh.runner.Runner; +import org.openjdk.jmh.runner.options.Options; +import org.openjdk.jmh.runner.options.OptionsBuilder; +import org.openjdk.jmh.runner.options.VerboseMode; + +public class BenchmarkMain { + + static { + + try { + CreateJsonTestFiles.create(); + } catch (final Exception e) { + e.printStackTrace(); + } + + //initialize Buffers + Buffers.init(); + } + + private static final String REGEX = ".*"; + private static final String MEMORY = "4096m"; + + public static void main(final String[] args) throws Exception { + //run(1,1,1,3); + run(1, 2, 3, 5); //1 fork, 2 threads, 3 warmup, 5 measurement + //run(1, 4, 3, 5); + //run(2,8,5,10); + //run(2,16,3,5); + } + + public static void run(final int forks, final int threads, final int warmupit, final int measureit) throws Exception { + + long start = System.currentTimeMillis(); + Options opt = new OptionsBuilder().include(REGEX).forks(forks).warmupIterations(warmupit).measurementIterations(measureit) + .threads(threads).mode(Mode.AverageTime).timeUnit(TimeUnit.MICROSECONDS).verbosity(VerboseMode.EXTRA) + .jvmArgs("-Xmx"+MEMORY, "-Dfile.encoding=utf-8") + .resultFormat(ResultFormatType.TEXT) + .result(String.format("avg_benchmark_jmh_result_f%d_t%d_w%d_i%d.txt", forks, threads, warmupit, measureit)) + .output(String.format("avg_benchmark_jmh_log_f%d_t%d_w%d_i%d.txt", forks, threads, warmupit, measureit)) + + .build(); + + new Runner(opt).run(); + + opt = new OptionsBuilder().include(REGEX).forks(forks).warmupIterations(warmupit).measurementIterations(measureit) + .threads(threads).mode(Mode.Throughput).timeUnit(TimeUnit.SECONDS).verbosity(VerboseMode.EXTRA) + .jvmArgs("-Xmx" + MEMORY, "-Dfile.encoding=utf-8") + .resultFormat(ResultFormatType.TEXT) + .result(String.format("thr_benchmark_jmh_result_f%d_t%d_w%d_i%d.txt", forks, threads, warmupit, measureit)) + .output(String.format("thr_benchmark_jmh_log_f%d_t%d_w%d_i%d.txt", forks, threads, warmupit, measureit)) + + .build(); + + new Runner(opt).run(); + long end = System.currentTimeMillis(); + + System.out.println("End. Runtime was "+((end-start)/(60*1000))+" min."); + + } + +} diff --git a/fleece-benchmark/src/test/java/org/apache/fleece/core/jmh/benchmark/BenchmarkStreamParser.java b/fleece-benchmark/src/test/java/org/apache/fleece/core/jmh/benchmark/BenchmarkStreamParser.java new file mode 100644 index 0000000..21444f0 --- /dev/null +++ b/fleece-benchmark/src/test/java/org/apache/fleece/core/jmh/benchmark/BenchmarkStreamParser.java @@ -0,0 +1,270 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fleece.core.jmh.benchmark; + +import java.io.CharArrayReader; +import java.io.InputStream; +import java.io.Reader; +import java.nio.charset.Charset; +import java.util.Collections; +import java.util.Map; + +import javax.json.Json; +import javax.json.JsonReader; +import javax.json.JsonReaderFactory; +import javax.json.JsonStructure; +import javax.json.stream.JsonParser; +import javax.json.stream.JsonParser.Event; +import javax.json.stream.JsonParserFactory; + +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.infra.Blackhole; + +@State(Scope.Benchmark) +public class BenchmarkStreamParser { + + protected Charset utf8Charset = Charset.forName("UTF8"); + + protected Map getConfig() { + return Collections.EMPTY_MAP; + } + + protected Charset getUtfCharset() { + return utf8Charset; + } + + public BenchmarkStreamParser() { + super(); + if (!Charset.defaultCharset().equals(Charset.forName("UTF-8"))) { + throw new RuntimeException("Default charset is " + Charset.defaultCharset() + ", must must be UTF-8"); + } + } + + protected final JsonParserFactory parserFactory = Json.createParserFactory(getConfig()); + protected final JsonReaderFactory readerFactory = Json.createReaderFactory(getConfig()); + + protected Object parse(final InputStream stream, final Blackhole bh) throws Exception { + final JsonParser parser = parserFactory.createParser(stream, getUtfCharset()); + + while (parser.hasNext()) { + final Event e = parser.next(); + bh.consume(e); + } + parser.close(); + return parser; + } + + protected Object parse(final Reader reader, final Blackhole bh) throws Exception { + final JsonParser parser = parserFactory.createParser(reader); + + while (parser.hasNext()) { + final Event e = parser.next(); + bh.consume(e); + } + parser.close(); + return parser; + } + + protected Object read(final InputStream stream, final Blackhole bh) throws Exception { + final JsonReader jreader = readerFactory.createReader(stream, getUtfCharset()); + final JsonStructure js = jreader.read(); + bh.consume(js); + jreader.close(); + return jreader; + } + + protected Object read(final Reader reader, final Blackhole bh) throws Exception { + final JsonReader jreader = readerFactory.createReader(reader); + final JsonStructure js = jreader.read(); + bh.consume(js); + jreader.close(); + return jreader; + } + + //-- parse bytes + /* + @Benchmark + public void parse_only_1k_bytes(final Blackhole bh) throws Exception { + bh.consume(parse(new ByteArrayInputStream(Buffers.B_1K), bh)); + } + + @Benchmark + public void parse_only_3k_bytes(final Blackhole bh) throws Exception { + bh.consume(parse(new ByteArrayInputStream(Buffers.B_3K), bh)); + } + + @Benchmark + public void parse_only_10k_bytes(final Blackhole bh) throws Exception { + bh.consume(parse(new ByteArrayInputStream(Buffers.B_10K), bh)); + } + + @Benchmark + public void parse_only_100k_bytes(final Blackhole bh) throws Exception { + bh.consume(parse(new ByteArrayInputStream(Buffers.B_100K), bh)); + } + + @Benchmark + public void parse_only_1000k_bytes(final Blackhole bh) throws Exception { + bh.consume(parse(new ByteArrayInputStream(Buffers.B_1000K), bh)); + } + + @Benchmark + public void parse_only_100000k_bytes(final Blackhole bh) throws Exception { + bh.consume(parse(new ByteArrayInputStream(Buffers.B_100000K), bh)); + } + */ + //-- parse chars + + @Benchmark + public void parse_only_1k_chars(final Blackhole bh) throws Exception { + bh.consume(parse(new CharArrayReader(Buffers.C_1K), bh)); + } + + @Benchmark + public void parse_only_3k_chars(final Blackhole bh) throws Exception { + bh.consume(parse(new CharArrayReader(Buffers.C_3K), bh)); + } + + @Benchmark + public void parse_only_10k_chars(final Blackhole bh) throws Exception { + bh.consume(parse(new CharArrayReader(Buffers.C_10K), bh)); + } + + @Benchmark + public void parse_only_100k_chars(final Blackhole bh) throws Exception { + bh.consume(parse(new CharArrayReader(Buffers.C_100K), bh)); + } + + @Benchmark + public void parse_only_1000k_chars(final Blackhole bh) throws Exception { + bh.consume(parse(new CharArrayReader(Buffers.C_1000K), bh)); + } + + @Benchmark + public void parse_only_100000k_chars(final Blackhole bh) throws Exception { + bh.consume(parse(new CharArrayReader(Buffers.C_100000K), bh)); + } + + //-- read bytes to structure + /* + @Benchmark + public void read_1k_bytes(final Blackhole bh) throws Exception { + bh.consume(read(new ByteArrayInputStream(Buffers.B_1K), bh)); + } + + @Benchmark + public void read_3k_bytes(final Blackhole bh) throws Exception { + bh.consume(read(new ByteArrayInputStream(Buffers.B_3K), bh)); + } + + @Benchmark + public void read_10k_bytes(final Blackhole bh) throws Exception { + bh.consume(read(new ByteArrayInputStream(Buffers.B_10K), bh)); + } + + @Benchmark + public void read_100k_bytes(final Blackhole bh) throws Exception { + bh.consume(read(new ByteArrayInputStream(Buffers.B_100K), bh)); + } + + @Benchmark + public void read_1000k_bytes(final Blackhole bh) throws Exception { + bh.consume(read(new ByteArrayInputStream(Buffers.B_1000K), bh)); + } + + @Benchmark + public void read_100000k_bytes(final Blackhole bh) throws Exception { + bh.consume(read(new ByteArrayInputStream(Buffers.B_100000K), bh)); + } + + //-- read chars to structure + + @Benchmark + public void read_1k_chars(final Blackhole bh) throws Exception { + bh.consume(read(new CharArrayReader(Buffers.C_1K), bh)); + } + */ + @Benchmark + public void read_3k_chars(final Blackhole bh) throws Exception { + bh.consume(read(new CharArrayReader(Buffers.C_3K), bh)); + } + + @Benchmark + public void read_10k_chars(final Blackhole bh) throws Exception { + bh.consume(read(new CharArrayReader(Buffers.C_10K), bh)); + } + + @Benchmark + public void read_100k_chars(final Blackhole bh) throws Exception { + bh.consume(read(new CharArrayReader(Buffers.C_100K), bh)); + } + + @Benchmark + public void read_1000k_chars(final Blackhole bh) throws Exception { + bh.consume(read(new CharArrayReader(Buffers.C_1000K), bh)); + } + + @Benchmark + public void read_100000k_chars(final Blackhole bh) throws Exception { + bh.consume(read(new CharArrayReader(Buffers.C_100000K), bh)); + } + + @Benchmark + public void parse_only_combined_chars(final Blackhole bh) throws Exception { + bh.consume(parse(new CharArrayReader(Buffers.C_100K), bh)); + bh.consume(parse(new CharArrayReader(Buffers.C_100K), bh)); + bh.consume(parse(new CharArrayReader(Buffers.C_100K), bh)); + bh.consume(parse(new CharArrayReader(Buffers.C_100K), bh)); + bh.consume(parse(new CharArrayReader(Buffers.C_100K), bh)); + + } + + /* @Benchmark + public void parse_only_combined_bytes(final Blackhole bh) throws Exception { + bh.consume(parse(new ByteArrayInputStream(Buffers.B_100K), bh)); + bh.consume(parse(new ByteArrayInputStream(Buffers.B_100K), bh)); + bh.consume(parse(new ByteArrayInputStream(Buffers.B_100K), bh)); + bh.consume(parse(new ByteArrayInputStream(Buffers.B_100K), bh)); + bh.consume(parse(new ByteArrayInputStream(Buffers.B_100K), bh)); + + } + */ + @Benchmark + public void read_combined_chars(final Blackhole bh) throws Exception { + bh.consume(read(new CharArrayReader(Buffers.C_100K), bh)); + bh.consume(read(new CharArrayReader(Buffers.C_100K), bh)); + bh.consume(read(new CharArrayReader(Buffers.C_100K), bh)); + bh.consume(read(new CharArrayReader(Buffers.C_100K), bh)); + bh.consume(read(new CharArrayReader(Buffers.C_100K), bh)); + + } + /* + @Benchmark + public void read_combined_bytes(final Blackhole bh) throws Exception { + bh.consume(read(new ByteArrayInputStream(Buffers.B_100K), bh)); + bh.consume(read(new ByteArrayInputStream(Buffers.B_100K), bh)); + bh.consume(read(new ByteArrayInputStream(Buffers.B_100K), bh)); + bh.consume(read(new ByteArrayInputStream(Buffers.B_100K), bh)); + bh.consume(read(new ByteArrayInputStream(Buffers.B_100K), bh)); + + } + */ +} diff --git a/fleece-benchmark/src/test/java/org/apache/fleece/core/jmh/benchmark/Buffers.java b/fleece-benchmark/src/test/java/org/apache/fleece/core/jmh/benchmark/Buffers.java new file mode 100644 index 0000000..1658cbd --- /dev/null +++ b/fleece-benchmark/src/test/java/org/apache/fleece/core/jmh/benchmark/Buffers.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fleece.core.jmh.benchmark; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.Charset; + +import org.apache.commons.io.IOUtils; + +public class Buffers { + + public static final byte[] B_1K = readBytes(1); + public static final byte[] B_3K = readBytes(3); + public static final byte[] B_10K = readBytes(10); + public static final byte[] B_100K = readBytes(100); + public static final byte[] B_1000K = readBytes(1000); + public static final byte[] B_100000K = readBytes(100000); + + public static final char[] C_1K = readChars(1); + public static final char[] C_3K = readChars(3); + public static final char[] C_10K = readChars(10); + public static final char[] C_100K = readChars(100); + public static final char[] C_1000K = readChars(1000); + public static final char[] C_100000K = readChars(100000); + + private static byte[] readBytes(final int count) { + + InputStream in = null; + try { + return IOUtils.toByteArray(in = Buffers.class.getResourceAsStream("/bench/generated_benchmark_test_file_" + count + "kb.json")); + } catch (final IOException e) { + return null; + } finally { + IOUtils.closeQuietly(in); + } + + } + + private static char[] readChars(final int count) { + + InputStream in = null; + try { + return IOUtils.toCharArray(in = Buffers.class.getResourceAsStream("/bench/generated_benchmark_test_file_" + count + "kb.json"), + Charset.forName("UTF-8")); + } catch (final IOException e) { + return null; + } finally { + IOUtils.closeQuietly(in); + } + } + + public static void init() { + + } +} diff --git a/fleece-benchmark/src/test/java/org/apache/fleece/core/jmh/benchmark/CreateJsonTestFiles.java b/fleece-benchmark/src/test/java/org/apache/fleece/core/jmh/benchmark/CreateJsonTestFiles.java new file mode 100644 index 0000000..380d8c7 --- /dev/null +++ b/fleece-benchmark/src/test/java/org/apache/fleece/core/jmh/benchmark/CreateJsonTestFiles.java @@ -0,0 +1,144 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fleece.core.jmh.benchmark; + +import java.io.File; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.output.FileWriterWithEncoding; + +public class CreateJsonTestFiles { + + public static void main(final String[] args) throws Exception { + + create(); + } + + public static void create() throws Exception { + + final String path = "./target/test-classes/bench"; + final File dir = new File(path).getAbsoluteFile(); + dir.mkdirs(); + + System.out.println("Create files to " + dir.getAbsolutePath()); + + createUnicodeString(path + "/generated_benchmark_test_file_unicodes.txt"); + create(path, 1); + create(path, 3); + create(path, 10); + create(path, 30); + create(path, 100); + create(path, 1000); + create(path, 100000); + //create(path, 1000000); + } + + public static File createUnicodeString(final String path) throws Exception { + + final StringBuilder sb = new StringBuilder(); + + for (char c = 0; c < '\u0a14'; c++) { + sb.append(c); + } + + for (int i = 0; i < 8; i++) { + sb.append(sb); + } + + final File file = new File(path); + FileUtils.write(file, sb.toString(), Charset.forName("UTF-8")); + return file; + } + + public static File create(final String path, final int count) throws Exception { + + if (count < 0 || path == null || path.length() == 0) { + throw new IllegalArgumentException(); + } + + final File json = new File(path + "/" + "generated_benchmark_test_file_" + count + "kb.json"); + final FileWriterWithEncoding sb = new FileWriterWithEncoding(json, StandardCharsets.UTF_8); + + sb.append("{\n"); + + for (int i = 0; i < count; i++) { + + sb.append("\t\"special-" + i + "\":" + "\"" + "\\\\f\\n\\r\\t\\uffff\udbff\udfff" + "\",\n"); + sb.append("\t\"unicode-\\u0000- " + i + "\":\"\\u5656\udbff\udfff\",\n"); + sb.append("\t\"\uffffbigdecimal" + i + "\":7817265.00000111,\n"); + sb.append("\t\"bigdecimal-2-" + i + "\":127655512123456.761009E-123,\n"); + sb.append("\t\"string-" + i + "\":\"lorem ipsum, ÄÖÜäöü.-,