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;
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  
37  /**
38   * Executes benchmark to compare the speed of generation of random numbers
39   * from the various source providers.
40   */
41  @BenchmarkMode(Mode.AverageTime)
42  @OutputTimeUnit(TimeUnit.MICROSECONDS)
43  @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
44  @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
45  @State(Scope.Benchmark)
46  @Fork(value = 1, jvmArgs = {"-server", "-Xms128M", "-Xmx128M"})
47  public class GenerationPerformance {
48      /**
49       * The benchmark state (retrieve the various "RandomSource"s).
50       */
51      @State(Scope.Benchmark)
52      public static class Sources {
53          /**
54           * RNG providers.
55           */
56          @Param({"JDK",
57                  "WELL_512_A",
58                  "WELL_1024_A",
59                  "WELL_19937_A",
60                  "WELL_19937_C",
61                  "WELL_44497_A",
62                  "WELL_44497_B",
63                  "MT",
64                  "ISAAC",
65                  "SPLIT_MIX_64",
66                  "MWC_256",
67                  "KISS",
68                  "XOR_SHIFT_1024_S",
69                  "TWO_CMRES",
70                  "MT_64" })
71          private String randomSourceName;
72  
73          /** RNG. */
74          private UniformRandomProvider provider;
75  
76          /**
77           * @return the RNG.
78           */
79          public UniformRandomProvider getGenerator() {
80              return provider;
81          }
82  
83          /** Intantiates generator. */
84          @Setup
85          public void setup() {
86              final RandomSource randomSource = RandomSource.valueOf(randomSourceName);
87              provider = RandomSource.create(randomSource);
88          }
89      }
90  
91      /**
92       * Number of random values to generate.
93       */
94      @Param({"1", "100", "10000", "1000000"})
95      private int numValues;
96  
97      /**
98       * @param sources Source of randomness.
99       * @param bh Data sink.
100      */
101     @Benchmark
102     public void nextBoolean(Sources sources,
103                             Blackhole bh) {
104         for (int i = 0; i < numValues; i++) {
105             bh.consume(sources.getGenerator().nextBoolean());
106         }
107     }
108 
109     /**
110      * @param sources Source of randomness.
111      * @param bh Data sink.
112      */
113     @Benchmark
114     public void nextInt(Sources sources,
115                         Blackhole bh) {
116         for (int i = 0; i < numValues; i++) {
117             bh.consume(sources.getGenerator().nextInt());
118         }
119     }
120 
121     /**
122      * @param sources Source of randomness.
123      * @param bh Data sink.
124      */
125     @Benchmark
126     public void nextIntN(Sources sources,
127                          Blackhole bh) {
128         final int n = 10;
129         for (int i = 0; i < numValues; i++) {
130             bh.consume(sources.getGenerator().nextInt(n));
131         }
132     }
133 
134     /**
135      * @param sources Source of randomness.
136      * @param bh Data sink.
137      */
138     @Benchmark
139     public void nextLong(Sources sources,
140                          Blackhole bh) {
141         for (int i = 0; i < numValues; i++) {
142             bh.consume(sources.getGenerator().nextLong());
143         }
144     }
145 
146     /**
147      * @param sources Source of randomness.
148      * @param bh Data sink.
149      */
150     @Benchmark
151     public void nextLongN(Sources sources,
152                           Blackhole bh) {
153         final long n = 2L * Integer.MAX_VALUE;
154         for (int i = 0; i < numValues; i++) {
155             bh.consume(sources.getGenerator().nextLong(n));
156         }
157     }
158 
159     /**
160      * @param sources Source of randomness.
161      * @param bh Data sink.
162      */
163     @Benchmark
164     public void nextFloat(Sources sources,
165                           Blackhole bh) {
166         for (int i = 0; i < numValues; i++) {
167             bh.consume(sources.getGenerator().nextFloat());
168         }
169     }
170 
171     /**
172      * @param sources Source of randomness.
173      * @param bh Data sink.
174      */
175     @Benchmark
176     public void nextDouble(Sources sources,
177                            Blackhole bh) {
178         for (int i = 0; i < numValues; i++) {
179             bh.consume(sources.getGenerator().nextDouble());
180         }
181     }
182 
183     /**
184      * @param sources Source of randomness.
185      * @param bh Data sink.
186      */
187     @Benchmark
188     public void nextBytes(Sources sources,
189                           Blackhole bh) {
190         final byte[] result = new byte[numValues];
191         sources.getGenerator().nextBytes(result);
192         bh.consume(result);
193     }
194 }