Class ZigguratSamplerPerformance
- java.lang.Object
-
- org.apache.commons.rng.examples.jmh.sampling.distribution.ZigguratSamplerPerformance
-
public class ZigguratSamplerPerformance extends Object
Executes a benchmark to compare the speed of generation of random numbers using variations of the ziggurat method.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classZigguratSamplerPerformance.DiffSourcesDefines method to use for creating two randomlongvalues in ascending order.static classZigguratSamplerPerformance.ExpSourcesDefines method to use for computingexp(x)when-8 <= x <= 0.static classZigguratSamplerPerformance.IndexCompareSourcesDefines method to use for creating an index values from a random long and comparing it to anintlimit.static classZigguratSamplerPerformance.IndexSourcesDefines method to use for creatingintindex values from a random long.static classZigguratSamplerPerformance.InterpolationSourcesDefines method to use for interpolating the X or Y tables from unsignedlongvalues.static classZigguratSamplerPerformance.LongSourcesDefines method to use for creating unsignedlongvalues.static classZigguratSamplerPerformance.SequentialSourcesThe samplers to use for testing the ziggurat method with sequential sample generation.static classZigguratSamplerPerformance.SignBitSourcesDefines method to extract a sign bit from alongvalue.static classZigguratSamplerPerformance.SingleSourcesThe samplers to use for testing the ziggurat method with single sample generation.static classZigguratSamplerPerformance.SourcesThe samplers to use for testing the ziggurat method.
-
Constructor Summary
Constructors Constructor Description ZigguratSamplerPerformance()
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description doublebaseline()Baseline for the JMH timing overhead for production of andoublevalue.intcompareIndex(ZigguratSamplerPerformance.IndexCompareSources sources)Benchmark methods for obtaining an index from the lower bits of a long and comparing them to a limit then returning the index as anint.long[]diff(ZigguratSamplerPerformance.DiffSources sources)Benchmark methods for obtaining 2 random longs in ascending order.doubleexp(ZigguratSamplerPerformance.ExpSources sources)Benchmark methods for obtainingexp(z)when-8 <= z <= 0.intgetIndex(ZigguratSamplerPerformance.IndexSources sources)Benchmark methods for obtaining an index from the lower bits of a long.longgetUnsignedLong(ZigguratSamplerPerformance.LongSources sources)Benchmark methods for obtaining an unsigned long.doubleinterpolate(ZigguratSamplerPerformance.InterpolationSources sources)Benchmark methods for obtaining an interpolated value from an unsigned long.doublesample(ZigguratSamplerPerformance.SingleSources sources)Run the sampler.doublesequentialSample(ZigguratSamplerPerformance.SequentialSources sources)Run the sampler to generate a number of samples sequentially.doublesignBit(ZigguratSamplerPerformance.SignBitSources sources)Benchmark methods for obtaining a sign value from a long.
-
-
-
Constructor Detail
-
ZigguratSamplerPerformance
public ZigguratSamplerPerformance()
-
-
Method Detail
-
baseline
public double baseline()
Baseline for the JMH timing overhead for production of andoublevalue.- Returns:
- the
doublevalue
-
getIndex
public int getIndex(ZigguratSamplerPerformance.IndexSources sources)
Benchmark methods for obtaining an index from the lower bits of a long.Note: This is disabled as there is no measurable difference between methods.
- Parameters:
sources- Source of randomness.- Returns:
- the sample value
-
compareIndex
public int compareIndex(ZigguratSamplerPerformance.IndexCompareSources sources)
Benchmark methods for obtaining an index from the lower bits of a long and comparing them to a limit then returning the index as anint.Note: This is disabled as there is no measurable difference between methods.
- Parameters:
sources- Source of randomness.- Returns:
- the sample value
-
getUnsignedLong
public long getUnsignedLong(ZigguratSamplerPerformance.LongSources sources)
Benchmark methods for obtaining an unsigned long.Note: This is disabled. Either there is no measurable difference between methods or the bit shift method is marginally faster depending on JDK and platform.
- Parameters:
sources- Source of randomness.- Returns:
- the sample value
-
interpolate
public double interpolate(ZigguratSamplerPerformance.InterpolationSources sources)
Benchmark methods for obtaining an interpolated value from an unsigned long.Note: This is disabled. The speed is typically: U1, 1minusU2, U_1minusU.
- Parameters:
sources- Source of randomness.- Returns:
- the sample value
-
signBit
public double signBit(ZigguratSamplerPerformance.SignBitSources sources)
Benchmark methods for obtaining a sign value from a long.Note: This is disabled. The branchless versions using a subtraction of 2 - 1 or 0 - 1 are faster.
- Parameters:
sources- Source of randomness.- Returns:
- the sample value
-
diff
public long[] diff(ZigguratSamplerPerformance.DiffSources sources)
Benchmark methods for obtaining 2 random longs in ascending order.Note: This is disabled. The branchless versions using a ternary conditional assignment are faster. This may not manifest as a performance improvement when used in the ziggurat sampler as it is not on the hot path (i.e. sampling inside the ziggurat).
- Parameters:
sources- Source of randomness.- Returns:
- the sample value
-
exp
public double exp(ZigguratSamplerPerformance.ExpSources sources)
Benchmark methods for obtainingexp(z)when-8 <= z <= 0.Note: This is disabled. On JDK 8 FastMath is faster. On JDK 11 Math.exp is a hotspot intrinsic and may be faster based on the platform architecture. Example results:
JDK 8 JDK 11 i7-6820HQ E5-1680 i7-6820HQ E5-1680 3960X noop 4.523 3.871 4.351 4.206 3.936 Math.exp 61.350 48.519 22.552 19.195 12.568 FastMath.exp 33.858 24.469 31.396 24.568 11.159The ziggurat sampler avoids calls to Math.exp in the majority of cases when using McFarland's fast method for overhangs which exploit the known maximum difference between pdf(x) and the triangle hypotenuse. Example data of the frequency that Math.exp is called per sample from the base implementations (using n=2^31):
Calls FastOverhangs SimpleOverhangs Exp exp(-x) 0.00271 0.0307 Normal exp(-0.5*x*x) 0.00359 0.0197* * Increases to 0.0198 if the tail exponential sampler uses simple overhangsNote that the maximum difference between pdf(x) and the triangle hypotenuse is smaller for the exponential distribution; thus the fast method can avoid using Math.exp more often. In the case of simple overhangs the normal distribution has more region covered by the ziggurat thus has a lower frequency of overhang sampling.
A significant speed-up of the exp function may improve run-time of the simple overhangs method. Any effect on the fast method is less likely to be noticed. This is observed in benchmark times which show an improvement of the simple overhangs method for the exponential relative to other methods on JDK 11 vs 8. However the simple overhangs is still slower as the exponential distribution is always concave and upper-right triangle samples are avoided by the fast overhang method.
- Parameters:
sources- Source of randomness.- Returns:
- the sample value
-
sample
public double sample(ZigguratSamplerPerformance.SingleSources sources)
Run the sampler.- Parameters:
sources- Source of randomness.- Returns:
- the sample value
-
sequentialSample
public double sequentialSample(ZigguratSamplerPerformance.SequentialSources sources)
Run the sampler to generate a number of samples sequentially.- Parameters:
sources- Source of randomness.- Returns:
- the sample value
-
-