View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.rng.examples.jmh.distribution;
19  
20  import org.openjdk.jmh.annotations.Benchmark;
21  import org.openjdk.jmh.annotations.BenchmarkMode;
22  import org.openjdk.jmh.annotations.Mode;
23  import org.openjdk.jmh.annotations.Warmup;
24  import org.openjdk.jmh.annotations.Measurement;
25  import org.openjdk.jmh.annotations.State;
26  import org.openjdk.jmh.annotations.Fork;
27  import org.openjdk.jmh.annotations.Scope;
28  import org.openjdk.jmh.annotations.Param;
29  import org.openjdk.jmh.annotations.Setup;
30  import org.openjdk.jmh.annotations.OutputTimeUnit;
31  import org.openjdk.jmh.infra.Blackhole;
32  import java.util.concurrent.TimeUnit;
33  
34  import org.apache.commons.rng.UniformRandomProvider;
35  import org.apache.commons.rng.simple.RandomSource;
36  import org.apache.commons.rng.sampling.distribution.ContinuousSampler;
37  import org.apache.commons.rng.sampling.distribution.DiscreteSampler;
38  import org.apache.commons.rng.sampling.distribution.BoxMullerNormalizedGaussianSampler;
39  import org.apache.commons.rng.sampling.distribution.MarsagliaNormalizedGaussianSampler;
40  import org.apache.commons.rng.sampling.distribution.ZigguratNormalizedGaussianSampler;
41  import org.apache.commons.rng.sampling.distribution.AhrensDieterExponentialSampler;
42  import org.apache.commons.rng.sampling.distribution.AhrensDieterMarsagliaTsangGammaSampler;
43  import org.apache.commons.rng.sampling.distribution.LogNormalSampler;
44  import org.apache.commons.rng.sampling.distribution.ChengBetaSampler;
45  import org.apache.commons.rng.sampling.distribution.ContinuousUniformSampler;
46  import org.apache.commons.rng.sampling.distribution.DiscreteUniformSampler;
47  import org.apache.commons.rng.sampling.distribution.RejectionInversionZipfSampler;
48  import org.apache.commons.rng.sampling.distribution.PoissonSampler;
49  
50  /**
51   * Executes benchmark to compare the speed of generation of random numbers
52   * from the various source providers.
53   */
54  @BenchmarkMode(Mode.AverageTime)
55  @OutputTimeUnit(TimeUnit.MICROSECONDS)
56  @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
57  @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
58  @State(Scope.Benchmark)
59  @Fork(value = 1, jvmArgs = {"-server", "-Xms128M", "-Xmx128M"})
60  public class SamplersPerformance {
61      /** Number of samples per run. */
62      private static final int NUM_SAMPLES = 10000000;
63  
64      /**
65       * The benchmark state (retrieve the various "RandomSource"s).
66       */
67      @State(Scope.Benchmark)
68      public static class Sources {
69          /**
70           * RNG providers.
71           */
72          @Param({"JDK",
73                  "WELL_512_A",
74                  "WELL_1024_A",
75                  "WELL_19937_A",
76                  "WELL_19937_C",
77                  "WELL_44497_A",
78                  "WELL_44497_B",
79                  "MT",
80                  "ISAAC",
81                  "SPLIT_MIX_64",
82                  "MWC_256",
83                  "KISS",
84                  "XOR_SHIFT_1024_S",
85                  "TWO_CMRES",
86                  "MT_64" })
87          private String randomSourceName;
88  
89          /** RNG. */
90          private UniformRandomProvider generator;
91  
92          /**
93           * @return the RNG.
94           */
95          public UniformRandomProvider getGenerator() {
96              return generator;
97          }
98  
99          /** Intantiates generator. */
100         @Setup
101         public void setup() {
102             final RandomSource randomSource = RandomSource.valueOf(randomSourceName);
103             generator = RandomSource.create(randomSource);
104         }
105     }
106 
107     /**
108      * Exercises a continuous sampler.
109      *
110      * @param sampler Sampler.
111      * @param bh Data sink.
112      */
113     private void runSample(ContinuousSampler sampler,
114                            Blackhole bh) {
115         for (int i = 0; i < NUM_SAMPLES; i++) {
116             bh.consume(sampler.sample());
117         }
118     }
119 
120     /**
121      * Exercises a discrete sampler.
122      *
123      * @param sampler Sampler.
124      * @param bh Data sink.
125      */
126     private void runSample(DiscreteSampler sampler,
127                            Blackhole bh) {
128         for (int i = 0; i < NUM_SAMPLES; i++) {
129             bh.consume(sampler.sample());
130         }
131     }
132 
133     // Benchmarks methods below.
134 
135     /**
136      * @param sources Source of randomness.
137      * @param bh Data sink.
138      */
139     @Benchmark
140     public void runBoxMullerNormalizedGaussianSampler(Sources sources,
141                                                       Blackhole bh) {
142         runSample(new BoxMullerNormalizedGaussianSampler(sources.getGenerator()), bh);
143     }
144 
145     /**
146      * @param sources Source of randomness.
147      * @param bh Data sink.
148      */
149     @Benchmark
150     public void runMarsagliaNormalizedGaussianSampler(Sources sources,
151                                                       Blackhole bh) {
152         runSample(new MarsagliaNormalizedGaussianSampler(sources.getGenerator()), bh);
153     }
154 
155     /**
156      * @param sources Source of randomness.
157      * @param bh Data sink.
158      */
159     @Benchmark
160     public void runZigguratNormalizedGaussianSampler(Sources sources,
161                                                      Blackhole bh) {
162         runSample(new ZigguratNormalizedGaussianSampler(sources.getGenerator()), bh);
163     }
164 
165     /**
166      * @param sources Source of randomness.
167      * @param bh Data sink.
168      */
169     @Benchmark
170     public void runAhrensDieterExponentialSampler(Sources sources,
171                                                   Blackhole bh) {
172         runSample(new AhrensDieterExponentialSampler(sources.getGenerator(), 4.56), bh);
173     }
174 
175     /**
176      * @param sources Source of randomness.
177      * @param bh Data sink.
178      */
179     @Benchmark
180     public void runAhrensDieterMarsagliaTsangGammaSampler(Sources sources,
181                                                           Blackhole bh) {
182         runSample(new AhrensDieterMarsagliaTsangGammaSampler(sources.getGenerator(), 9.8, 0.76), bh);
183     }
184 
185     /**
186      * @param sources Source of randomness.
187      * @param bh Data sink.
188      */
189     @Benchmark
190     public void runBoxMullerLogNormalSampler(Sources sources,
191                                              Blackhole bh) {
192         runSample(new LogNormalSampler(new BoxMullerNormalizedGaussianSampler(sources.getGenerator()), 12.3, 4.6), bh);
193     }
194 
195     /**
196      * @param sources Source of randomness.
197      * @param bh Data sink.
198      */
199     @Benchmark
200     public void runMarsagliaLogNormalSampler(Sources sources,
201                                              Blackhole bh) {
202         runSample(new LogNormalSampler(new MarsagliaNormalizedGaussianSampler(sources.getGenerator()), 12.3, 4.6), bh);
203     }
204 
205     /**
206      * @param sources Source of randomness.
207      * @param bh Data sink.
208      */
209     @Benchmark
210     public void runZigguratLogNormalSampler(Sources sources,
211                                             Blackhole bh) {
212         runSample(new LogNormalSampler(new ZigguratNormalizedGaussianSampler(sources.getGenerator()), 12.3, 4.6), bh);
213     }
214 
215     /**
216      * @param sources Source of randomness.
217      * @param bh Data sink.
218      */
219     @Benchmark
220     public void runChengBetaSampler(Sources sources,
221                                     Blackhole bh) {
222         runSample(new ChengBetaSampler(sources.getGenerator(), 0.45, 6.7), bh);
223     }
224 
225     /**
226      * @param sources Source of randomness.
227      * @param bh Data sink.
228      */
229     @Benchmark
230     public void runContinuousUniformSampler(Sources sources,
231                                             Blackhole bh) {
232         runSample(new ContinuousUniformSampler(sources.getGenerator(), 123.4, 5678.9), bh);
233     }
234 
235     /**
236      * @param sources Source of randomness.
237      * @param bh Data sink.
238      */
239     @Benchmark
240     public void runDiscreteUniformSampler(Sources sources,
241                                           Blackhole bh) {
242         runSample(new DiscreteUniformSampler(sources.getGenerator(), -98, 76), bh);
243     }
244 
245     /**
246      * @param sources Source of randomness.
247      * @param bh Data sink.
248      */
249     @Benchmark
250     public void runRejectionInversionZipfSampler(Sources sources,
251                                                  Blackhole bh) {
252         runSample(new RejectionInversionZipfSampler(sources.getGenerator(), 43, 2.1), bh);
253     }
254 
255     /**
256      * @param sources Source of randomness.
257      * @param bh Data sink.
258      */
259     @Benchmark
260     public void runPoissonSampler(Sources sources,
261                                   Blackhole bh) {
262         runSample(new PoissonSampler(sources.getGenerator(), 8.9), bh);
263     }
264 }