[
https://issues.apache.org/jira/browse/RNG-151?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17375454#comment-17375454
]
Alex Herbert commented on RNG-151:
----------------------------------
I have collected all implementations into one benchmark. All samplers use a
table size of 256 unless otherwise stated.
||Type||Java||Description||
|Gaussian128|ZigguratNormalizedGaussianSampler.of(rng)|Marsaglia ziggurat
Gaussian sampler using a table size of 128|
|Gaussian256|new ZigguratNormalizedGaussianSampler256(rng) (JMH
examples)|Marsaglia ziggurat Gaussian sampler using a table size of 256|
|Exponential|new ZigguratExponentialSampler(rng) (JMH examples)|Marsaglia
ziggurat exponential sampler|
|ModGaussian|ModifiedZigguratSampler.Gaussian.of(rng)|McFarland modified
ziggurat Gaussian sampler|
|ModExponential|ModifiedZigguratSampler.Exponential.of(rng)|McFarland modified
ziggurat exponential sampler|
|ModGaussian2|new ModifiedZigguratNormalizedGaussianSampler(rng) (JMH
examples)|McFarland modified ziggurat Gaussian sampler in a single class|
|ModExponential2|new ModifiedZigguratExponentialSampler(rng) (JMH
examples)|McFarland modified ziggurat exponential sampler in a single class|
I included the original separate class versions of the modified ziggurat method
to compare with the new version which has them as nested classes. This was to
check if the change affected the speed. It actually makes the modified Gaussian
sampler marginally faster:
{noformat}
VM version: JDK 1.8.0_241, Java HotSpot(TM) 64-Bit Server VM, 25.241-b07
Benchmark (randomSourceName) (type) Mode
Cnt Score Error Units
ZigguratSamplerPerformance.baseline N/A N/A avgt
5 2.278 ± 0.026 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP Gaussian128 avgt
5 13.005 ± 0.115 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP Gaussian256 avgt
5 11.195 ± 0.016 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP Exponential avgt
5 7.001 ± 0.014 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP ModGaussian avgt
5 7.042 ± 0.545 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP ModExponential avgt
5 5.817 ± 0.017 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP ModGaussian2 avgt
5 7.296 ± 0.056 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP ModExponential2 avgt
5 5.841 ± 0.071 ns/op
VM version: JDK 11.0.6, Java HotSpot(TM) 64-Bit Server VM, 11.0.6+8-LTS
Benchmark (randomSourceName) (type) Mode
Cnt Score Error Units
ZigguratSamplerPerformance.baseline N/A N/A avgt
5 2.401 ± 0.003 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP Gaussian128 avgt
5 11.947 ± 0.520 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP Gaussian256 avgt
5 11.542 ± 0.071 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP Exponential avgt
5 6.672 ± 0.039 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP ModGaussian avgt
5 7.076 ± 0.027 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP ModExponential avgt
5 6.154 ± 0.015 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP ModGaussian2 avgt
5 7.311 ± 0.010 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP ModExponential2 avgt
5 6.149 ± 0.095 ns/op
VM version: JDK 11.0.11, OpenJDK 64-Bit Server VM,
11.0.11+9-Ubuntu-0ubuntu2.18.04
Benchmark (randomSourceName) (type) Mode
Cnt Score Error Units
ZigguratSamplerPerformance.baseline N/A N/A avgt
5 2.410 ± 0.074 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP Gaussian128 avgt
5 8.139 ± 0.019 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP Gaussian256 avgt
5 7.565 ± 0.020 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP Exponential avgt
5 6.574 ± 0.024 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP ModGaussian avgt
5 7.163 ± 0.042 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP ModExponential avgt
5 6.143 ± 0.005 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP ModGaussian2 avgt
5 7.311 ± 0.006 ns/op
ZigguratSamplerPerformance.sample XO_RO_SHI_RO_128_PP ModExponential2 avgt
5 6.329 ± 0.015 ns/op
{noformat}
h2. Conclusion
* The modified exponential is faster than the Marsaglia exponential, making
that class redundant.
* Increasing the Marsaglia Gaussian table size from 128 to 256 makes a
difference
* The modified Gaussian is faster than the Marsaglia Gaussian, even if used
with a table size of 256. So there is no requirement to increase the table size
in the current ZigguratNormalizedGaussianSampler. Users should switch to using
ModifiedZigguratSampler.Gaussian.
> Modified Ziggurat algorithm for normal and exponential sampling
> ---------------------------------------------------------------
>
> Key: RNG-151
> URL: https://issues.apache.org/jira/browse/RNG-151
> Project: Commons RNG
> Issue Type: Improvement
> Components: sampling
> Affects Versions: 1.3
> Reporter: Alex Herbert
> Priority: Major
>
> The following paper describes a modification of the ziggurat method for
> sampling normal and exponential deviates:
> {noformat}
> McFarland, C.D. (2016)
> "A modified ziggurat algorithm for generating exponentially and normally
> distributed pseudorandom numbers".
> Journal of Statistical Computation and Simulation 86, 1281-1294.
> {noformat}
> [McFarland (2016) JSCS 86,
> 1281-294|https://www.tandfonline.com/doi/abs/10.1080/00949655.2015.1060234]
> Note: This method is the one that has been chosen as the default
> implementation for the java.util.random.RandomGenerator nextGaussian and
> nextExponential methods to be added in JDK 17.
> The method should be investigated in comparison to the current ziggurat
> method of Marsaglia used in ZigguratNormalizedGaussianSampler and
> ZigguratExponentialSampler.
>
--
This message was sent by Atlassian Jira
(v8.3.4#803005)