You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datasketches.apache.org by le...@apache.org on 2019/12/02 18:43:04 UTC

[incubator-datasketches-characterization] 02/04: update with t-digest tests

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

leerho pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-datasketches-characterization.git

commit ea129216ce720edf974ba3e207cc09ac9a2fdf0f
Author: Lee Rhodes <le...@users.noreply.github.com>
AuthorDate: Sun Dec 1 14:24:12 2019 -0800

    update with t-digest tests
---
 .gitignore                                         |   2 +-
 .../quantiles/TDigestAccuracyProfile.java          |  51 ++++++++
 .../quantiles/TDigestSpeedProfile.java             | 142 +++++++++++++++++++++
 .../resources/quantiles/TDigestAccuracyJob.conf    |  10 ++
 src/main/resources/quantiles/TDigestSpeedJob.conf  |  10 ++
 5 files changed, 214 insertions(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index 85d7a51..3968d63 100644
--- a/.gitignore
+++ b/.gitignore
@@ -42,7 +42,7 @@ hs_err_pid*
 #Test config and output
 /target/
 test-output/
-local/
+local/**
 reports/
 .pmd
 tmp/
diff --git a/src/main/java/org/apache/datasketches/characterization/quantiles/TDigestAccuracyProfile.java b/src/main/java/org/apache/datasketches/characterization/quantiles/TDigestAccuracyProfile.java
new file mode 100644
index 0000000..36b22a5
--- /dev/null
+++ b/src/main/java/org/apache/datasketches/characterization/quantiles/TDigestAccuracyProfile.java
@@ -0,0 +1,51 @@
+package org.apache.datasketches.characterization.quantiles;
+
+import java.util.Arrays;
+
+import com.tdunning.math.stats.TDigest;
+import org.apache.datasketches.characterization.Properties;
+import org.apache.datasketches.characterization.quantiles.DataGenerator.Mode;
+
+public class TDigestAccuracyProfile extends QuantilesAccuracyProfile {
+
+  private int compression;
+  private double[] inputValues;
+  private DataGenerator gen;
+  private DoubleRankCalculator.Mode rankMode;
+
+  @Override
+  void configure(final Properties props) {
+    compression = Integer.parseInt(props.mustGet("compression"));
+    gen = new DataGenerator(Mode.valueOf(props.mustGet("data")));
+    rankMode = DoubleRankCalculator.Mode.valueOf(props.mustGet("rank"));
+  }
+
+  @Override
+  void prepareTrial(final int streamLength) {
+    inputValues = new double[streamLength];
+  }
+
+  @Override
+  double doTrial() {
+    gen.fillArray(inputValues);
+    
+    // build sketch
+    final TDigest sketch = TDigest.createDigest(compression);
+    for (int i = 0; i < inputValues.length; i++) {
+      sketch.add(inputValues[i]);
+    }
+
+    Arrays.sort(inputValues);
+
+    // query sketch and gather results
+    double maxRankError = 0;
+    final DoubleRankCalculator rank = new DoubleRankCalculator(inputValues, rankMode);
+    for (int i = 0; i < inputValues.length; i++) {
+      final double trueRank = rank.getRank(inputValues[i]);
+      final double estRank = sketch.cdf(inputValues[i]);
+      maxRankError = Math.max(maxRankError, Math.abs(trueRank - estRank));
+    }
+    return maxRankError;
+  }
+
+}
diff --git a/src/main/java/org/apache/datasketches/characterization/quantiles/TDigestSpeedProfile.java b/src/main/java/org/apache/datasketches/characterization/quantiles/TDigestSpeedProfile.java
new file mode 100644
index 0000000..bfec214
--- /dev/null
+++ b/src/main/java/org/apache/datasketches/characterization/quantiles/TDigestSpeedProfile.java
@@ -0,0 +1,142 @@
+package org.apache.datasketches.characterization.quantiles;
+
+import java.nio.ByteBuffer;
+
+import com.tdunning.math.stats.MergingDigest;
+import com.tdunning.math.stats.TDigest;
+import org.apache.datasketches.characterization.Properties;
+
+public class TDigestSpeedProfile extends QuantilesSpeedProfile {
+
+  private static final ByteBuffer buf = ByteBuffer.allocate(10000); // for serialization, more capacity than necessary
+  private int k;
+  private double[] inputValues;
+  private int numQueryValues;
+  private double[] queryValues;
+  private DataGenerator gen;
+
+  long buildTimeNs;
+  long updateTimeNs;
+  long getQuantileTimeNs;
+  long getRankTimeNs;
+  long serializeTimeNs;
+  long deserializeTimeNs;
+  long smallSerializeTimeNs;
+  long smallDeserializeTimeNs;
+  long numRetainedItems;
+  long serializedSizeBytes;
+  long smallSerializedSizeBytes;
+
+  @Override
+  void configure(final int k, final int numQueryValues, final Properties properties) {
+    this.k = k;
+    this.numQueryValues = numQueryValues;
+    gen = new DataGenerator(DataGenerator.Mode.Uniform);
+  }
+
+  @Override
+  void prepareTrial(final int streamLength) {
+    inputValues = new double[streamLength];
+    queryValues = new double[numQueryValues];
+    resetStats();
+  }
+
+  @SuppressWarnings("unused")
+  @Override
+  void doTrial() {
+    gen.fillArray(inputValues);
+    gen.fillArray(queryValues);
+
+    final long startBuild = System.nanoTime();
+    final TDigest sketch = TDigest.createDigest(k);
+    final long stopBuild = System.nanoTime();
+    buildTimeNs += stopBuild - startBuild;
+
+    final long startUpdate = System.nanoTime();
+    for (int i = 0; i < inputValues.length; i++) {
+      sketch.add(inputValues[i]);
+    }
+    final long stopUpdate = System.nanoTime();
+    updateTimeNs += stopUpdate - startUpdate;
+
+    final long startGetQuantile = System.nanoTime();
+    for (final double value: queryValues) {
+      sketch.quantile(value);
+    }
+    final long stopGetQuantile = System.nanoTime();
+    getQuantileTimeNs += stopGetQuantile - startGetQuantile;
+
+    final long startGetRank = System.nanoTime();
+    for (final double value: queryValues) {
+      sketch.cdf(value);
+    }
+    final long stopGetRank = System.nanoTime();
+    getRankTimeNs += stopGetRank - startGetRank;
+
+    buf.rewind();
+    final long startSerialize = System.nanoTime();
+    sketch.asBytes(buf);
+    final long stopSerialize = System.nanoTime();
+    serializeTimeNs += stopSerialize - startSerialize;
+    buf.rewind();
+    final long startDeserialize = System.nanoTime();
+    MergingDigest.fromBytes(buf);
+    final long stopDeserialize = System.nanoTime();
+    deserializeTimeNs += stopDeserialize - startDeserialize;
+    buf.rewind();
+    final long startSmallSerialize = System.nanoTime();
+    sketch.asSmallBytes(buf);
+    final long stopSmallSerialize = System.nanoTime();
+    smallSerializeTimeNs += stopSmallSerialize - startSmallSerialize;
+    buf.rewind();
+    final long startSmallDeserialize = System.nanoTime();
+    MergingDigest.fromBytes(buf);
+    final long stopSmallDeserialize = System.nanoTime();
+    smallDeserializeTimeNs += stopSmallDeserialize - startSmallDeserialize;
+
+    // could record the last one since they must be the same
+    // but let's average across all trials to see if there is an anomaly
+    numRetainedItems += sketch.centroidCount();
+    serializedSizeBytes += sketch.byteSize();
+    smallSerializedSizeBytes += sketch.smallByteSize();
+  }
+
+  @Override
+  String getHeader() {
+    return "Stream\tTrials\tBuild\tUpdate\tQuant\tCDF\tSer\tDe\tSer\tDe\tItems\tSize\tSmall";
+  }
+
+  @Override
+  String getStats(final int streamLength, final int numTrials, final int numQueryValues) {
+    return(String.format("%d\t%d\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%.1f\t%d\t%d\t%d",
+      streamLength,
+      numTrials,
+      (double) buildTimeNs / numTrials,
+      (double) updateTimeNs / numTrials / streamLength,
+      (double) getQuantileTimeNs / numTrials / numQueryValues,
+      (double) getRankTimeNs / numTrials / numQueryValues,
+      (double) serializeTimeNs / numTrials,
+      (double) deserializeTimeNs / numTrials,
+      (double) smallSerializeTimeNs / numTrials,
+      (double) smallDeserializeTimeNs / numTrials,
+      numRetainedItems / numTrials,
+      serializedSizeBytes / numTrials,
+      smallSerializedSizeBytes / numTrials
+    ));
+  }
+
+  private void resetStats() {
+    buildTimeNs = 0;
+    updateTimeNs = 0;
+    getQuantileTimeNs = 0;
+    getRankTimeNs = 0;
+    numRetainedItems = 0;
+    serializeTimeNs = 0;
+    deserializeTimeNs = 0;
+    smallSerializeTimeNs = 0;
+    smallDeserializeTimeNs = 0;
+    serializedSizeBytes = 0;
+    smallSerializedSizeBytes = 0;
+  }
+
+}
diff --git a/src/main/resources/quantiles/TDigestAccuracyJob.conf b/src/main/resources/quantiles/TDigestAccuracyJob.conf
new file mode 100644
index 0000000..7df7cf4
--- /dev/null
+++ b/src/main/resources/quantiles/TDigestAccuracyJob.conf
@@ -0,0 +1,10 @@
+JobProfile=com.yahoo.sketches.characterization.quantiles.TDigestAccuracyProfile
+compression=200 # sketch size and accuracy parameter
+errLgK=10 # parameter for the rank error distribution sketch
+errPct=99 # percentile of the rank error distribution to report
+trials=20 # Trials at every steam length
+lgMin=0  # The starting stream length
+lgMax=23 # How high the stream length goes
+PPO=16    # The horizontal x-resolution of trials points
+data=Gaussian # distribution of input data
+rank=Max # rank rule
diff --git a/src/main/resources/quantiles/TDigestSpeedJob.conf b/src/main/resources/quantiles/TDigestSpeedJob.conf
new file mode 100644
index 0000000..7a86a2c
--- /dev/null
+++ b/src/main/resources/quantiles/TDigestSpeedJob.conf
@@ -0,0 +1,10 @@
+JobProfile=com.yahoo.sketches.characterization.quantiles.TDigestSpeedProfile
+K=200 # sketch size and accuracy parameter
+numQueryValues=20 # number of values for getQuantiles(), getCDF() and getRank()
+
+lgMin=0  # The starting stream length
+lgMax=23 # How high the stream length goes
+PPO=16   # The horizontal x-resolution of trials points
+
+lgMaxTrials=16 # Max trials at start (low counts)
+lgMinTrials=9 # Min trials at tail (high counts)


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