You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datasketches.apache.org by jm...@apache.org on 2019/08/26 18:27:48 UTC

[incubator-datasketches-java] branch master updated: use ThreadLocalRandom instead of Random

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 89d067d  use ThreadLocalRandom instead of Random
     new 2f94e93  Merge pull request #267 from jgeraerts/master
89d067d is described below

commit 89d067d2e7c87ed1b380730e1cebcc89c4a50185
Author: Jo Geraerts <jo...@umask.net>
AuthorDate: Thu Aug 22 15:54:54 2019 +0200

    use ThreadLocalRandom instead of Random
    
    I was using The ReservoirItemsSketch in a multithreaded program.
    After replacing the normal java.util.Random by ThreadLocalRandom
    I had a significant improvement in performance.
---
 .../java/com/yahoo/sketches/sampling/ReservoirItemsSketch.java |  4 ++--
 .../java/com/yahoo/sketches/sampling/ReservoirItemsUnion.java  |  4 ++--
 .../java/com/yahoo/sketches/sampling/ReservoirLongsSketch.java |  4 ++--
 .../java/com/yahoo/sketches/sampling/ReservoirLongsUnion.java  |  4 ++--
 src/main/java/com/yahoo/sketches/sampling/SamplingUtil.java    | 10 +++++++---
 .../java/com/yahoo/sketches/sampling/VarOptItemsSketch.java    |  4 ++--
 .../java/com/yahoo/sketches/sampling/ReservoirSizeTest.java    |  2 +-
 .../com/yahoo/sketches/sampling/VarOptItemsSketchTest.java     |  2 +-
 8 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/src/main/java/com/yahoo/sketches/sampling/ReservoirItemsSketch.java b/src/main/java/com/yahoo/sketches/sampling/ReservoirItemsSketch.java
index bdbb16c..389409f 100644
--- a/src/main/java/com/yahoo/sketches/sampling/ReservoirItemsSketch.java
+++ b/src/main/java/com/yahoo/sketches/sampling/ReservoirItemsSketch.java
@@ -324,8 +324,8 @@ public final class ReservoirItemsSketch<T> {
       ++itemsSeen_;
       // prob(keep_item) < k / n = reservoirSize_ / itemsSeen_
       // so multiply to get: keep if rand * itemsSeen_ < reservoirSize_
-      if ((SamplingUtil.rand.nextDouble() * itemsSeen_) < reservoirSize_) {
-        final int newSlot = SamplingUtil.rand.nextInt(reservoirSize_);
+      if ((SamplingUtil.rand().nextDouble() * itemsSeen_) < reservoirSize_) {
+        final int newSlot = SamplingUtil.rand().nextInt(reservoirSize_);
         data_.set(newSlot, item);
       }
     }
diff --git a/src/main/java/com/yahoo/sketches/sampling/ReservoirItemsUnion.java b/src/main/java/com/yahoo/sketches/sampling/ReservoirItemsUnion.java
index e6eb6bd..3684c25 100644
--- a/src/main/java/com/yahoo/sketches/sampling/ReservoirItemsUnion.java
+++ b/src/main/java/com/yahoo/sketches/sampling/ReservoirItemsUnion.java
@@ -418,11 +418,11 @@ public final class ReservoirItemsUnion<T> {
 
       final double rescaled_one = targetTotal;
       assert (rescaled_prob < rescaled_one); // Use an exception to enforce strict lightness?
-      final double rescaled_flip = rescaled_one * SamplingUtil.rand.nextDouble();
+      final double rescaled_flip = rescaled_one * SamplingUtil.rand().nextDouble();
       if (rescaled_flip < rescaled_prob) {
         // Intentionally NOT doing optimization to extract slot number from rescaled_flip.
         // Grabbing new random bits to ensure all slots in play
-        final int slotNo = SamplingUtil.rand.nextInt(tgtK);
+        final int slotNo = SamplingUtil.rand().nextInt(tgtK);
         gadget_.insertValueAtPosition(source.getValueAtPosition(i), slotNo);
       } // end of inlined weight update
     } // end of loop over source samples
diff --git a/src/main/java/com/yahoo/sketches/sampling/ReservoirLongsSketch.java b/src/main/java/com/yahoo/sketches/sampling/ReservoirLongsSketch.java
index f242d17..b74c0a8 100644
--- a/src/main/java/com/yahoo/sketches/sampling/ReservoirLongsSketch.java
+++ b/src/main/java/com/yahoo/sketches/sampling/ReservoirLongsSketch.java
@@ -323,8 +323,8 @@ public final class ReservoirLongsSketch {
       ++itemsSeen_;
       // prob(keep_item) < k / n = reservoirSize_ / itemsSeen_
       // so multiply to get: keep if rand * itemsSeen_ < reservoirSize_
-      if ((SamplingUtil.rand.nextDouble() * itemsSeen_) < reservoirSize_) {
-        final int newSlot = SamplingUtil.rand.nextInt(reservoirSize_);
+      if ((SamplingUtil.rand().nextDouble() * itemsSeen_) < reservoirSize_) {
+        final int newSlot = SamplingUtil.rand().nextInt(reservoirSize_);
         data_[newSlot] = item;
       }
     }
diff --git a/src/main/java/com/yahoo/sketches/sampling/ReservoirLongsUnion.java b/src/main/java/com/yahoo/sketches/sampling/ReservoirLongsUnion.java
index 1786ed7..19b0733 100644
--- a/src/main/java/com/yahoo/sketches/sampling/ReservoirLongsUnion.java
+++ b/src/main/java/com/yahoo/sketches/sampling/ReservoirLongsUnion.java
@@ -370,11 +370,11 @@ public final class ReservoirLongsUnion {
 
       final double rescaled_one = targetTotal;
       assert (rescaled_prob < rescaled_one); // Use an exception to enforce strict lightness?
-      final double rescaled_flip = rescaled_one * SamplingUtil.rand.nextDouble();
+      final double rescaled_flip = rescaled_one * SamplingUtil.rand().nextDouble();
       if (rescaled_flip < rescaled_prob) {
         // Intentionally NOT doing optimization to extract slot number from rescaled_flip.
         // Grabbing new random bits to ensure all slots in play
-        final int slotNo = SamplingUtil.rand.nextInt(tgtK);
+        final int slotNo = SamplingUtil.rand().nextInt(tgtK);
         gadget_.insertValueAtPosition(source.getValueAtPosition(i), slotNo);
       } // end of inlined weight update
     } // end of loop over source samples
diff --git a/src/main/java/com/yahoo/sketches/sampling/SamplingUtil.java b/src/main/java/com/yahoo/sketches/sampling/SamplingUtil.java
index 3022328..11f7bca 100644
--- a/src/main/java/com/yahoo/sketches/sampling/SamplingUtil.java
+++ b/src/main/java/com/yahoo/sketches/sampling/SamplingUtil.java
@@ -23,6 +23,7 @@ import static com.yahoo.sketches.BoundsOnBinomialProportions.approximateLowerBou
 import static com.yahoo.sketches.BoundsOnBinomialProportions.approximateUpperBoundOnP;
 
 import java.util.Random;
+import java.util.concurrent.ThreadLocalRandom;
 
 /**
  * Common utility functions for the sampling family of sketches.
@@ -36,7 +37,6 @@ final class SamplingUtil {
    */
   private static final double DEFAULT_KAPPA = 2.0;
 
-  public static final Random rand = new Random();
 
   private SamplingUtil() {}
 
@@ -56,9 +56,9 @@ final class SamplingUtil {
   }
 
   static double nextDoubleExcludeZero() {
-    double r = rand.nextDouble();
+    double r = rand().nextDouble();
     while (r == 0.0) {
-      r = rand.nextDouble();
+      r = rand().nextDouble();
     }
     return r;
   }
@@ -78,4 +78,8 @@ final class SamplingUtil {
     final double adjustedKappa = DEFAULT_KAPPA * Math.sqrt(1 - samplingRate);
     return approximateLowerBoundOnP(n, k, adjustedKappa);
   }
+
+  public static Random rand() {
+    return ThreadLocalRandom.current();
+  }
 }
diff --git a/src/main/java/com/yahoo/sketches/sampling/VarOptItemsSketch.java b/src/main/java/com/yahoo/sketches/sampling/VarOptItemsSketch.java
index 45f6ec6..e7fc9ca 100644
--- a/src/main/java/com/yahoo/sketches/sampling/VarOptItemsSketch.java
+++ b/src/main/java/com/yahoo/sketches/sampling/VarOptItemsSketch.java
@@ -899,7 +899,7 @@ public final class VarOptItemsSketch<T> {
       // pure reservoir mode, so can simply eject a randomly chosen sample from the reservoir
       assert r_ >= 2;
 
-      final int rIdxToDelete = 1 + SamplingUtil.rand.nextInt(r_); // 1 for the gap
+      final int rIdxToDelete = 1 + SamplingUtil.rand().nextInt(r_); // 1 for the gap
       final int rightmostRIdx = (1 + r_) - 1;
       swapValues(rIdxToDelete, rightmostRIdx);
       weights_.set(rightmostRIdx, -1.0);
@@ -1153,7 +1153,7 @@ public final class VarOptItemsSketch<T> {
     if (r_ == 1) {
       return offset;
     } else {
-      return offset + SamplingUtil.rand.nextInt(r_);
+      return offset + SamplingUtil.rand().nextInt(r_);
     }
   }
 
diff --git a/src/test/java/com/yahoo/sketches/sampling/ReservoirSizeTest.java b/src/test/java/com/yahoo/sketches/sampling/ReservoirSizeTest.java
index 66cef94..12d4d24 100644
--- a/src/test/java/com/yahoo/sketches/sampling/ReservoirSizeTest.java
+++ b/src/test/java/com/yahoo/sketches/sampling/ReservoirSizeTest.java
@@ -108,7 +108,7 @@ public class ReservoirSizeTest {
     final int numIters = 100;
 
     for (int i = 0; i < numIters; ++i) {
-      final int input = SamplingUtil.rand.nextInt(maxValue) + 1;
+      final int input = SamplingUtil.rand().nextInt(maxValue) + 1;
       final int result = ReservoirSize.decodeValue(ReservoirSize.computeSize(input));
 
       // result must be no smaller than input
diff --git a/src/test/java/com/yahoo/sketches/sampling/VarOptItemsSketchTest.java b/src/test/java/com/yahoo/sketches/sampling/VarOptItemsSketchTest.java
index 6c0de3b..ff0bbb3 100644
--- a/src/test/java/com/yahoo/sketches/sampling/VarOptItemsSketchTest.java
+++ b/src/test/java/com/yahoo/sketches/sampling/VarOptItemsSketchTest.java
@@ -296,7 +296,7 @@ public class VarOptItemsSketchTest {
     for (long i = 0; i < n; ++i) {
       // generate weights above and below 1.0 using w ~ exp(5*N(0,1)) which covers about
       // 10 orders of magnitude
-      final double w = Math.exp(5 * SamplingUtil.rand.nextGaussian());
+      final double w = Math.exp(5 * SamplingUtil.rand().nextGaussian());
       inputSum += w;
       sketch.update(i, w);
     }


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