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.sampling.distribution;
19  
20  import org.apache.commons.rng.UniformRandomProvider;
21  import org.apache.commons.rng.examples.jmh.RandomSources;
22  import org.apache.commons.rng.sampling.distribution.AhrensDieterExponentialSampler;
23  import org.apache.commons.rng.sampling.distribution.AhrensDieterMarsagliaTsangGammaSampler;
24  import org.apache.commons.rng.sampling.distribution.BoxMullerNormalizedGaussianSampler;
25  import org.apache.commons.rng.sampling.distribution.ChengBetaSampler;
26  import org.apache.commons.rng.sampling.distribution.ContinuousSampler;
27  import org.apache.commons.rng.sampling.distribution.ContinuousUniformSampler;
28  import org.apache.commons.rng.sampling.distribution.InverseTransformParetoSampler;
29  import org.apache.commons.rng.sampling.distribution.LevySampler;
30  import org.apache.commons.rng.sampling.distribution.LogNormalSampler;
31  import org.apache.commons.rng.sampling.distribution.MarsagliaNormalizedGaussianSampler;
32  import org.apache.commons.rng.sampling.distribution.StableSampler;
33  import org.apache.commons.rng.sampling.distribution.TSampler;
34  import org.apache.commons.rng.sampling.distribution.ZigguratSampler;
35  import org.apache.commons.rng.sampling.distribution.ZigguratNormalizedGaussianSampler;
36  
37  import org.openjdk.jmh.annotations.Benchmark;
38  import org.openjdk.jmh.annotations.BenchmarkMode;
39  import org.openjdk.jmh.annotations.Fork;
40  import org.openjdk.jmh.annotations.Measurement;
41  import org.openjdk.jmh.annotations.Mode;
42  import org.openjdk.jmh.annotations.OutputTimeUnit;
43  import org.openjdk.jmh.annotations.Param;
44  import org.openjdk.jmh.annotations.Scope;
45  import org.openjdk.jmh.annotations.Setup;
46  import org.openjdk.jmh.annotations.State;
47  import org.openjdk.jmh.annotations.Warmup;
48  
49  import java.util.concurrent.TimeUnit;
50  
51  /**
52   * Executes benchmark to compare the speed of generation of random numbers
53   * from the various source providers for different types of {@link ContinuousSampler}.
54   */
55  @BenchmarkMode(Mode.AverageTime)
56  @OutputTimeUnit(TimeUnit.NANOSECONDS)
57  @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
58  @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
59  @State(Scope.Benchmark)
60  @Fork(value = 1, jvmArgs = {"-server", "-Xms128M", "-Xmx128M"})
61  public class ContinuousSamplersPerformance {
62      /**
63       * The value.
64       *
65       * <p>This must NOT be final!</p>
66       */
67      private double value;
68  
69      /**
70       * The {@link ContinuousSampler} samplers to use for testing. Creates the sampler for each
71       * {@link org.apache.commons.rng.simple.RandomSource RandomSource} in the default
72       * {@link RandomSources}.
73       */
74      @State(Scope.Benchmark)
75      public static class Sources extends RandomSources {
76          /**
77           * The sampler type.
78           */
79          @Param({"BoxMullerNormalizedGaussianSampler",
80                  "MarsagliaNormalizedGaussianSampler",
81                  "ZigguratNormalizedGaussianSampler",
82                  "ZigguratSampler.NormalizedGaussian",
83                  "AhrensDieterExponentialSampler",
84                  "ZigguratSampler.Exponential",
85                  "AhrensDieterGammaSampler",
86                  "MarsagliaTsangGammaSampler",
87                  "LevySampler",
88                  "LogNormalBoxMullerNormalizedGaussianSampler",
89                  "LogNormalMarsagliaNormalizedGaussianSampler",
90                  "LogNormalZigguratNormalizedGaussianSampler",
91                  "LogNormalSampler.ZigguratSampler.NormalizedGaussian",
92                  "ChengBetaSampler",
93                  "ContinuousUniformSampler",
94                  "InverseTransformParetoSampler",
95                  "StableSampler",
96                  "TSampler"})
97          private String samplerType;
98  
99          /** The sampler. */
100         private ContinuousSampler sampler;
101 
102         /**
103          * @return the sampler.
104          */
105         public ContinuousSampler getSampler() {
106             return sampler;
107         }
108 
109         /** Instantiates sampler. */
110         @Override
111         @Setup
112         public void setup() {
113             super.setup();
114             final UniformRandomProvider rng = getGenerator();
115             if ("BoxMullerNormalizedGaussianSampler".equals(samplerType)) {
116                 sampler = BoxMullerNormalizedGaussianSampler.of(rng);
117             } else if ("MarsagliaNormalizedGaussianSampler".equals(samplerType)) {
118                 sampler = MarsagliaNormalizedGaussianSampler.of(rng);
119             } else if ("ZigguratNormalizedGaussianSampler".equals(samplerType)) {
120                 sampler = ZigguratNormalizedGaussianSampler.of(rng);
121             } else if ("ZigguratSampler.NormalizedGaussian".equals(samplerType)) {
122                 sampler = ZigguratSampler.NormalizedGaussian.of(rng);
123             } else if ("AhrensDieterExponentialSampler".equals(samplerType)) {
124                 sampler = AhrensDieterExponentialSampler.of(rng, 4.56);
125             } else if ("ZigguratSampler.Exponential".equals(samplerType)) {
126                 sampler = ZigguratSampler.Exponential.of(rng, 4.56);
127             } else if ("AhrensDieterGammaSampler".equals(samplerType)) {
128                 // This tests the Ahrens-Dieter algorithm since alpha < 1
129                 sampler = AhrensDieterMarsagliaTsangGammaSampler.of(rng, 0.76, 9.8);
130             } else if ("MarsagliaTsangGammaSampler".equals(samplerType)) {
131                 // This tests the Marsaglia-Tsang algorithm since alpha > 1
132                 sampler = AhrensDieterMarsagliaTsangGammaSampler.of(rng, 12.34, 9.8);
133             } else if ("LevySampler".equals(samplerType)) {
134                 sampler = LevySampler.of(rng, 1.23, 4.56);
135             } else if ("LogNormalBoxMullerNormalizedGaussianSampler".equals(samplerType)) {
136                 sampler = LogNormalSampler.of(BoxMullerNormalizedGaussianSampler.of(rng), 12.3, 4.6);
137             } else if ("LogNormalMarsagliaNormalizedGaussianSampler".equals(samplerType)) {
138                 sampler = LogNormalSampler.of(MarsagliaNormalizedGaussianSampler.of(rng), 12.3, 4.6);
139             } else if ("LogNormalZigguratNormalizedGaussianSampler".equals(samplerType)) {
140                 sampler = LogNormalSampler.of(ZigguratNormalizedGaussianSampler.of(rng), 12.3, 4.6);
141             } else if ("LogNormalSampler.ZigguratSampler.NormalizedGaussian".equals(samplerType)) {
142                 sampler = LogNormalSampler.of(ZigguratSampler.NormalizedGaussian.of(rng), 12.3, 4.6);
143             } else if ("ChengBetaSampler".equals(samplerType)) {
144                 sampler = ChengBetaSampler.of(rng, 0.45, 6.7);
145             } else if ("ContinuousUniformSampler".equals(samplerType)) {
146                 sampler = ContinuousUniformSampler.of(rng, 123.4, 5678.9);
147             } else if ("InverseTransformParetoSampler".equals(samplerType)) {
148                 sampler = InverseTransformParetoSampler.of(rng, 23.45, 0.1234);
149             } else if ("StableSampler".equals(samplerType)) {
150                 sampler = StableSampler.of(rng, 1.3, 0.2);
151             } else if ("TSampler".equals(samplerType)) {
152                 sampler = TSampler.of(rng, 1.23);
153             }
154         }
155     }
156 
157     // Benchmarks methods below.
158 
159     /**
160      * Baseline for the JMH timing overhead for production of an {@code double} value.
161      *
162      * @return the {@code double} value
163      */
164     @Benchmark
165     public double baseline() {
166         return value;
167     }
168 
169     /**
170      * Run the sampler.
171      *
172      * @param sources Source of randomness.
173      * @return the sample value
174      */
175     @Benchmark
176     public double sample(Sources sources) {
177         return sources.getSampler().sample();
178     }
179 }