]> source.dussan.org Git - sonarqube.git/commitdiff
Improve microbenchmark templates
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Thu, 12 Feb 2015 14:14:04 +0000 (15:14 +0100)
committerSimon Brandhof <simon.brandhof@sonarsource.com>
Thu, 12 Feb 2015 14:14:19 +0000 (15:14 +0100)
microbenchmark-template/pom.xml
microbenchmark-template/run.sh
microbenchmark-template/src/main/java/org/sonar/microbenchmark/FileSourceDbBenchmark.java [new file with mode: 0644]
microbenchmark-template/src/main/java/org/sonar/microbenchmark/SerializationBenchmark.java
pom.xml

index 3d8695ba8caa355f351c5b57fd790e4fe8ec063d..7a07993a8b81cfa9e0ec3e3605683baca27702ec 100644 (file)
       <artifactId>sonar-plugin-api</artifactId>
       <version>${project.version}</version>
     </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>sonar-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
     <dependency>
       <groupId>com.google.code.gson</groupId>
       <artifactId>gson</artifactId>
index db9c373374dadd8eac4cb8f92e21a34e513b421e..ab222188dee07c94dcd29d930f1be40ceed94010 100755 (executable)
@@ -5,4 +5,4 @@
 # Example: run.sh org.sonar.microbenchmark.SerializationBenchmark
 
 mvn clean install
-java -jar target/microbenchmark.jar -i 5 -wi 5 -f 5 $*
+java -jar target/microbenchmark.jar $*
diff --git a/microbenchmark-template/src/main/java/org/sonar/microbenchmark/FileSourceDbBenchmark.java b/microbenchmark-template/src/main/java/org/sonar/microbenchmark/FileSourceDbBenchmark.java
new file mode 100644 (file)
index 0000000..99bd0c1
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.microbenchmark;
+
+import com.google.protobuf.CodedOutputStream;
+import org.apache.commons.lang.RandomStringUtils;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+import org.openjdk.jmh.runner.Runner;
+import org.openjdk.jmh.runner.RunnerException;
+import org.openjdk.jmh.runner.options.Options;
+import org.openjdk.jmh.runner.options.OptionsBuilder;
+import org.sonar.server.source.db.FileSourceDb;
+
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ *
+ * See https://code.google.com/p/xxhash/ and https://github.com/jpountz/lz4-java
+ *
+ */
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@State(Scope.Thread)
+@Fork(1)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@BenchmarkMode(Mode.Throughput)
+public class FileSourceDbBenchmark {
+
+  @Param({"10", "100", "1000", "100000"})
+  public int linesNumber;
+
+  List<FileSourceDb.Line> lines = new ArrayList<>();
+  FileSourceDb.Data data;
+
+  @Setup
+  public void setup() throws Exception {
+    FileSourceDb.Data.Builder builder = FileSourceDb.Data.newBuilder();
+    for (int i = 0; i < linesNumber; i++) {
+      FileSourceDb.Line.Builder lineBuilder = builder.addLinesBuilder();
+      lines.add(lineBuilder
+        .setLine(i + 1)
+        .setScmAuthor("charlie")
+        .setScmRevision("ABCDE")
+        .setScmDate(15000000000L)
+        .setUtLineHits(5)
+        .setUtConditions(2)
+        .setUtCoveredConditions(1)
+        .setSource(RandomStringUtils.randomAlphanumeric(10))
+        .setHighlighting(RandomStringUtils.randomAlphanumeric(20))
+        .setSymbols(RandomStringUtils.randomAlphanumeric(20))
+        .addAllDuplications(Arrays.asList(12,13,15))
+        .build());
+    }
+    data = builder.build();
+  }
+
+  @Benchmark
+  public int container() throws Exception {
+    ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
+    data.writeTo(byteOutput);
+    byteOutput.close();
+    return byteOutput.toByteArray().length;
+  }
+
+  @Benchmark
+  public int delimiters() throws Exception {
+    ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
+    for (FileSourceDb.Line line : lines) {
+      line.writeDelimitedTo(byteOutput);
+    }
+    byteOutput.close();
+    return byteOutput.toByteArray().length;
+  }
+
+  @Benchmark
+  public int codedstream_container() throws Exception {
+    ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
+    CodedOutputStream writer = CodedOutputStream.newInstance(byteOutput);
+    writer.writeRawVarint32(data.getSerializedSize());
+    writer.writeRawBytes(data.toByteArray());
+    writer.flush();
+    byteOutput.close();
+    return byteOutput.toByteArray().length;
+  }
+
+  @Benchmark
+  public int codedstream_container_known_size() throws Exception {
+    ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(data.getSerializedSize());
+    CodedOutputStream writer = CodedOutputStream.newInstance(byteOutput);
+    writer.writeRawVarint32(data.getSerializedSize());
+    writer.writeRawBytes(data.toByteArray());
+    writer.flush();
+    byteOutput.close();
+    return byteOutput.toByteArray().length;
+  }
+
+  @Benchmark
+  public int codedstream_delimiters() throws Exception {
+    ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
+    CodedOutputStream writer = CodedOutputStream.newInstance(byteOutput);
+    for (FileSourceDb.Line line : lines) {
+      writer.writeRawVarint32(line.getSerializedSize());
+      writer.writeRawBytes(line.toByteArray());
+    }
+    writer.flush();
+    byteOutput.close();
+    return byteOutput.toByteArray().length;
+  }
+
+  /**
+   * You can this benchmark with maven command-line (see run.sh) or by executing this method
+   * in IDE
+   */
+  public static void main(String[] args) throws RunnerException {
+    Options opt = new OptionsBuilder()
+      .include(FileSourceDbBenchmark.class.getSimpleName())
+      .build();
+    new Runner(opt).run();
+  }
+}
index 8c599a82c87f4a895e043c644e54503f92b0c3eb..7286eabff3b890d8b6da15fb22b5f6a2c1b35b0e 100644 (file)
@@ -25,9 +25,15 @@ import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 import com.google.gson.stream.JsonWriter;
 import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
 import org.openjdk.jmh.annotations.Scope;
 import org.openjdk.jmh.annotations.Setup;
 import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
 import org.openjdk.jmh.runner.Runner;
 import org.openjdk.jmh.runner.RunnerException;
 import org.openjdk.jmh.runner.options.Options;
@@ -49,8 +55,14 @@ import java.io.OutputStream;
 import java.io.Serializable;
 import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
 @State(Scope.Thread)
+@Fork(1)
+@Warmup(iterations = 5)
+@Measurement(iterations = 5)
+@BenchmarkMode(Mode.Throughput)
 public class SerializationBenchmark {
 
   File outputFile;
@@ -186,9 +198,6 @@ public class SerializationBenchmark {
   public static void main(String[] args) throws RunnerException {
     Options opt = new OptionsBuilder()
       .include(SerializationBenchmark.class.getSimpleName())
-      .warmupIterations(5)
-      .measurementIterations(5)
-      .forks(5)
       .build();
     new Runner(opt).run();
   }
diff --git a/pom.xml b/pom.xml
index 57b1e8ba2780d189df8e5786941945cf4e2586cc..ee6004292c06bea3be247945004fcc45ef42d703 100644 (file)
--- a/pom.xml
+++ b/pom.xml
         </dependency>
       </dependencies>
     </profile>
+    <profile>
+      <!-- add microbenchmarks module to IDE -->
+      <id>includeMicrobenchmarkModule</id>
+      <modules>
+        <module>microbenchmark-template</module>
+      </modules>
+    </profile>
   </profiles>
 
 </project>