You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pinot.apache.org by ja...@apache.org on 2019/06/28 05:01:17 UTC

[incubator-pinot] branch off-heap-bench created (now 57fc6cc)

This is an automated email from the ASF dual-hosted git repository.

jackie pushed a change to branch off-heap-bench
in repository https://gitbox.apache.org/repos/asf/incubator-pinot.git.


      at 57fc6cc  Offheap String Dictionary Benchmark

This branch includes the following new commits:

     new 57fc6cc  Offheap String Dictionary Benchmark

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org


[incubator-pinot] 01/01: Offheap String Dictionary Benchmark

Posted by ja...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

jackie pushed a commit to branch off-heap-bench
in repository https://gitbox.apache.org/repos/asf/incubator-pinot.git

commit 57fc6ccb66db88acf53e0f4157dbb51e3cbd43c8
Author: Jackie (Xiaotian) Jiang <xa...@linkedin.com>
AuthorDate: Thu Jun 27 21:58:45 2019 -0700

    Offheap String Dictionary Benchmark
    
    Enhance BenchmarkStringDictionary to benchmark read/write for on-heap/off-heap mutable dictionary for string of different lengths
    
    Benchmark                                               (_maxValueLength)  Mode  Cnt     Score     Error  Units
    BenchmarkStringDictionary.offHeapStringDictionaryRead                   8  avgt    5   198.729 ±  82.008  ms/op
    BenchmarkStringDictionary.offHeapStringDictionaryRead                  16  avgt    5   224.921 ±  32.696  ms/op
    BenchmarkStringDictionary.offHeapStringDictionaryRead                  32  avgt    5   342.644 ± 209.424  ms/op
    BenchmarkStringDictionary.offHeapStringDictionaryRead                  64  avgt    5   360.047 ± 101.929  ms/op
    BenchmarkStringDictionary.offHeapStringDictionaryRead                 128  avgt    5   484.173 ± 113.249  ms/op
    BenchmarkStringDictionary.offHeapStringDictionaryRead                 256  avgt    5   611.015 ± 316.933  ms/op
    BenchmarkStringDictionary.offHeapStringDictionaryRead                 512  avgt    5   813.054 ±  80.827  ms/op
    BenchmarkStringDictionary.offHeapStringDictionaryRead                1024  avgt    5  1178.064 ±  35.517  ms/op
    BenchmarkStringDictionary.offHeapStringDictionaryWrite                  8  avgt    5   210.411 ±  75.758  ms/op
    BenchmarkStringDictionary.offHeapStringDictionaryWrite                 16  avgt    5   242.633 ±  48.765  ms/op
    BenchmarkStringDictionary.offHeapStringDictionaryWrite                 32  avgt    5   296.329 ±  70.063  ms/op
    BenchmarkStringDictionary.offHeapStringDictionaryWrite                 64  avgt    5   373.348 ±  72.213  ms/op
    BenchmarkStringDictionary.offHeapStringDictionaryWrite                128  avgt    5   476.224 ± 103.509  ms/op
    BenchmarkStringDictionary.offHeapStringDictionaryWrite                256  avgt    5   594.346 ± 249.458  ms/op
    BenchmarkStringDictionary.offHeapStringDictionaryWrite                512  avgt    5   841.739 ±  74.731  ms/op
    BenchmarkStringDictionary.offHeapStringDictionaryWrite               1024  avgt    5  1241.271 ±  54.812  ms/op
    BenchmarkStringDictionary.onHeapStringDictionaryRead                    8  avgt    5    69.934 ±   6.722  ms/op
    BenchmarkStringDictionary.onHeapStringDictionaryRead                   16  avgt    5    67.843 ±  10.101  ms/op
    BenchmarkStringDictionary.onHeapStringDictionaryRead                   32  avgt    5    75.276 ±   3.305  ms/op
    BenchmarkStringDictionary.onHeapStringDictionaryRead                   64  avgt    5    54.462 ±   7.237  ms/op
    BenchmarkStringDictionary.onHeapStringDictionaryRead                  128  avgt    5    67.534 ±   7.629  ms/op
    BenchmarkStringDictionary.onHeapStringDictionaryRead                  256  avgt    5    64.138 ±  20.597  ms/op
    BenchmarkStringDictionary.onHeapStringDictionaryRead                  512  avgt    5    74.625 ±   1.658  ms/op
    BenchmarkStringDictionary.onHeapStringDictionaryRead                 1024  avgt    5    73.748 ±  23.128  ms/op
    BenchmarkStringDictionary.onHeapStringDictionaryWrite                   8  avgt    5    90.023 ±  12.112  ms/op
    BenchmarkStringDictionary.onHeapStringDictionaryWrite                  16  avgt    5    94.689 ±  15.384  ms/op
    BenchmarkStringDictionary.onHeapStringDictionaryWrite                  32  avgt    5   102.102 ±  14.500  ms/op
    BenchmarkStringDictionary.onHeapStringDictionaryWrite                  64  avgt    5   108.548 ±  17.029  ms/op
    BenchmarkStringDictionary.onHeapStringDictionaryWrite                 128  avgt    5   110.598 ±  13.267  ms/op
    BenchmarkStringDictionary.onHeapStringDictionaryWrite                 256  avgt    5   118.573 ±  16.774  ms/op
    BenchmarkStringDictionary.onHeapStringDictionaryWrite                 512  avgt    5   125.380 ±  41.136  ms/op
    BenchmarkStringDictionary.onHeapStringDictionaryWrite                1024  avgt    5   130.772 ±  47.184  ms/op
---
 pinot-perf/pom.xml                                 |   4 +-
 .../pinot/perf/BenchmarkStringDictionary.java      | 118 +++++++++++++--------
 2 files changed, 75 insertions(+), 47 deletions(-)

diff --git a/pinot-perf/pom.xml b/pinot-perf/pom.xml
index a37057b..64b1891 100644
--- a/pinot-perf/pom.xml
+++ b/pinot-perf/pom.xml
@@ -98,7 +98,7 @@
     <dependency>
       <groupId>org.openjdk.jmh</groupId>
       <artifactId>jmh-core</artifactId>
-      <version>1.15</version>
+      <version>1.21</version>
       <exclusions>
         <exclusion>
           <groupId>net.sf.jopt-simple</groupId>
@@ -109,7 +109,7 @@
     <dependency>
       <groupId>org.openjdk.jmh</groupId>
       <artifactId>jmh-generator-annprocess</artifactId>
-      <version>1.15</version>
+      <version>1.21</version>
       <scope>provided</scope>
     </dependency>
     <dependency>
diff --git a/pinot-perf/src/main/java/org/apache/pinot/perf/BenchmarkStringDictionary.java b/pinot-perf/src/main/java/org/apache/pinot/perf/BenchmarkStringDictionary.java
index ffb295b..872ffcb 100644
--- a/pinot-perf/src/main/java/org/apache/pinot/perf/BenchmarkStringDictionary.java
+++ b/pinot-perf/src/main/java/org/apache/pinot/perf/BenchmarkStringDictionary.java
@@ -18,102 +18,130 @@
  */
 package org.apache.pinot.perf;
 
+import java.io.IOException;
 import java.util.Random;
 import java.util.concurrent.TimeUnit;
+import org.apache.pinot.common.utils.StringUtil;
 import org.apache.pinot.core.io.readerwriter.PinotDataBufferMemoryManager;
 import org.apache.pinot.core.io.writer.impl.DirectMemoryManager;
 import org.apache.pinot.core.realtime.impl.dictionary.StringOffHeapMutableDictionary;
 import org.apache.pinot.core.realtime.impl.dictionary.StringOnHeapMutableDictionary;
 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.TearDown;
-import org.openjdk.jmh.profile.GCProfiler;
-import org.openjdk.jmh.profile.HotspotMemoryProfiler;
+import org.openjdk.jmh.annotations.Warmup;
 import org.openjdk.jmh.runner.Runner;
 import org.openjdk.jmh.runner.options.ChainedOptionsBuilder;
 import org.openjdk.jmh.runner.options.OptionsBuilder;
-import org.openjdk.jmh.runner.options.TimeValue;
 
 
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@Warmup(iterations = 3, time = 3)
+@Measurement(iterations = 5, time = 3)
+@Fork(1)
 @State(Scope.Benchmark)
 public class BenchmarkStringDictionary {
-  private static final int ROW_COUNT = 2_500_000;
-  private static final int CARDINALITY = 1_000_000;
-  private static final int MAX_STRING_LEN = 32;
+  private static final int NUM_RECORDS = 1_000_000;
+  private static final int CARDINALITY = 200_000;
+  private static final Random RANDOM = new Random();
+
+  @Param({"8", "16", "32", "64", "128", "256", "512", "1024"})
+  private int _maxValueLength;
 
-  private String[] _stringValues;
   private PinotDataBufferMemoryManager _memoryManager;
+  private String[] _values;
+  private StringOffHeapMutableDictionary _offHeapDictionary;
+  private StringOnHeapMutableDictionary _onHeapDictionary;
 
   @Setup
   public void setUp() {
-    _memoryManager = new DirectMemoryManager(BenchmarkStringDictionary.class.getName());
-    // Create a list of values to insert into the hash map
-    String[] uniqueStrings = new String[CARDINALITY];
-    Random r = new Random();
-    for (int i = 0; i < uniqueStrings.length; i++) {
-      uniqueStrings[i] = generateRandomString(r, r.nextInt(MAX_STRING_LEN + 1));
+    _memoryManager = new DirectMemoryManager("");
+    _offHeapDictionary =
+        new StringOffHeapMutableDictionary(CARDINALITY, CARDINALITY / 10, _memoryManager, null, _maxValueLength / 2);
+    _onHeapDictionary = new StringOnHeapMutableDictionary();
+    String[] uniqueValues = new String[CARDINALITY];
+    for (int i = 0; i < CARDINALITY; i++) {
+      String value = generateRandomString(RANDOM.nextInt(_maxValueLength + 1));
+      uniqueValues[i] = value;
+      _offHeapDictionary.index(value);
+      _onHeapDictionary.index(value);
     }
-    _stringValues = new String[ROW_COUNT];
-    for (int i = 0; i < _stringValues.length; i++) {
-      int u = r.nextInt(CARDINALITY);
-      _stringValues[i] = uniqueStrings[u];
+    _values = new String[NUM_RECORDS];
+    for (int i = 0; i < NUM_RECORDS; i++) {
+      _values[i] = uniqueValues[RANDOM.nextInt(CARDINALITY)];
     }
   }
 
   @TearDown
   public void tearDown()
       throws Exception {
+    _onHeapDictionary.close();
+    _offHeapDictionary.close();
     _memoryManager.close();
   }
 
-  // Generates a ascii displayable string of given length
-  private String generateRandomString(Random r, final int len) {
-    byte[] bytes = new byte[len];
-    for (int i = 0; i < len; i++) {
-      bytes[i] = (byte) (r.nextInt(92) + 32);
+  // Generates a ascii displayable string of the given length
+  private String generateRandomString(int length) {
+    byte[] bytes = new byte[length];
+    for (int i = 0; i < length; i++) {
+      bytes[i] = (byte) (RANDOM.nextInt(0x7F - 0x20) + 0x20);
     }
-    return new String(bytes);
+    return StringUtil.decodeUtf8(bytes);
   }
 
   @Benchmark
-  @BenchmarkMode(Mode.SampleTime)
-  @OutputTimeUnit(TimeUnit.MILLISECONDS)
-  public StringOffHeapMutableDictionary benchmarkOffHeapStringDictionary() {
-    StringOffHeapMutableDictionary dictionary =
-        new StringOffHeapMutableDictionary(5000, 10, _memoryManager, "stringColumn", 32);
-
-    for (String stringValue : _stringValues) {
-      dictionary.index(stringValue);
+  public int offHeapStringDictionaryRead() {
+    int sum = 0;
+    for (String stringValue : _values) {
+      sum += _offHeapDictionary.indexOf(stringValue);
     }
-
-    return dictionary;
+    return sum;
   }
 
   @Benchmark
-  @BenchmarkMode(Mode.SampleTime)
-  @OutputTimeUnit(TimeUnit.MILLISECONDS)
-  public StringOnHeapMutableDictionary benchmarkOnHeapStringDictionary() {
-    StringOnHeapMutableDictionary dictionary = new StringOnHeapMutableDictionary();
+  public int onHeapStringDictionaryRead() {
+    int sum = 0;
+    for (String stringValue : _values) {
+      sum += _onHeapDictionary.indexOf(stringValue);
+    }
+    return sum;
+  }
 
-    for (String stringValue : _stringValues) {
-      dictionary.index(stringValue);
+  @Benchmark
+  public int offHeapStringDictionaryWrite()
+      throws IOException {
+    try (StringOffHeapMutableDictionary offHeapDictionary = new StringOffHeapMutableDictionary(CARDINALITY,
+        CARDINALITY / 10, _memoryManager, null, _maxValueLength / 2)) {
+      for (String stringValue : _values) {
+        offHeapDictionary.index(stringValue);
+      }
+      return offHeapDictionary.length();
     }
+  }
 
-    return dictionary;
+  @Benchmark
+  public int onHeapStringDictionaryWrite()
+      throws IOException {
+    try (StringOnHeapMutableDictionary onHeapDictionary = new StringOnHeapMutableDictionary()) {
+      for (String stringValue : _values) {
+        onHeapDictionary.index(stringValue);
+      }
+      return onHeapDictionary.length();
+    }
   }
 
   public static void main(String[] args)
       throws Exception {
-    ChainedOptionsBuilder opt =
-        new OptionsBuilder().include(BenchmarkStringDictionary.class.getSimpleName()).addProfiler(GCProfiler.class)
-            .addProfiler(HotspotMemoryProfiler.class).warmupTime(TimeValue.seconds(60)).warmupIterations(8)
-            .measurementTime(TimeValue.seconds(60)).measurementIterations(8).forks(5);
-
+    ChainedOptionsBuilder opt = new OptionsBuilder().include(BenchmarkStringDictionary.class.getSimpleName());
     new Runner(opt.build()).run();
   }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@pinot.apache.org
For additional commands, e-mail: commits-help@pinot.apache.org