1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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.sampling.distribution.DiscreteInverseCumulativeProbabilityFunction;
22 import org.apache.commons.rng.sampling.distribution.DiscreteSampler;
23 import org.apache.commons.rng.sampling.distribution.GeometricSampler;
24 import org.apache.commons.rng.sampling.distribution.InverseTransformDiscreteSampler;
25 import org.apache.commons.rng.simple.RandomSource;
26 import org.openjdk.jmh.annotations.Benchmark;
27 import org.openjdk.jmh.annotations.BenchmarkMode;
28 import org.openjdk.jmh.annotations.Fork;
29 import org.openjdk.jmh.annotations.Measurement;
30 import org.openjdk.jmh.annotations.Mode;
31 import org.openjdk.jmh.annotations.OutputTimeUnit;
32 import org.openjdk.jmh.annotations.Param;
33 import org.openjdk.jmh.annotations.Scope;
34 import org.openjdk.jmh.annotations.Setup;
35 import org.openjdk.jmh.annotations.State;
36 import org.openjdk.jmh.annotations.Warmup;
37
38 import java.util.concurrent.TimeUnit;
39
40
41
42
43
44 @BenchmarkMode(Mode.AverageTime)
45 @OutputTimeUnit(TimeUnit.NANOSECONDS)
46 @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
47 @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
48 @State(Scope.Benchmark)
49 @Fork(value = 1, jvmArgs = {"-server", "-Xms128M", "-Xmx128M"})
50 public class GeometricSamplersPerformance {
51
52
53
54
55
56 private int value;
57
58
59
60
61
62 @State(Scope.Benchmark)
63 public static class Sources {
64
65
66
67
68
69
70
71
72 @Param({"SPLIT_MIX_64",
73 "MWC_256",
74 "JDK"})
75 private String randomSourceName;
76
77
78
79
80 @Param({"0.1", "0.3"})
81 private double probabilityOfSuccess;
82
83
84
85
86 @Param({"GeometricSampler", "InverseTransformDiscreteSampler"})
87 private String samplerType;
88
89
90 private DiscreteSampler sampler;
91
92
93
94
95 public DiscreteSampler getSampler() {
96 return sampler;
97 }
98
99
100 @Setup
101 public void setup() {
102 final RandomSource randomSource = RandomSource.valueOf(randomSourceName);
103 final UniformRandomProvider rng = randomSource.create();
104 if ("GeometricSampler".equals(samplerType)) {
105 sampler = GeometricSampler.of(rng, probabilityOfSuccess);
106 } else {
107 final DiscreteInverseCumulativeProbabilityFunction geometricFunction =
108 new GeometricDiscreteInverseCumulativeProbabilityFunction(probabilityOfSuccess);
109 sampler = InverseTransformDiscreteSampler.of(rng, geometricFunction);
110 }
111 }
112 }
113
114
115
116
117
118
119 private static class GeometricDiscreteInverseCumulativeProbabilityFunction
120 implements DiscreteInverseCumulativeProbabilityFunction {
121
122
123
124 private final double log1mProbabilityOfSuccess;
125
126
127
128
129 GeometricDiscreteInverseCumulativeProbabilityFunction(double probabilityOfSuccess) {
130
131 log1mProbabilityOfSuccess = Math.log1p(-probabilityOfSuccess);
132 }
133
134 @Override
135 public int inverseCumulativeProbability(double cumulativeProbability) {
136
137
138
139
140
141
142
143
144
145
146
147 return Math.max(0, (int) Math.ceil(Math.log1p(-cumulativeProbability) / log1mProbabilityOfSuccess - 1));
148 }
149 }
150
151
152
153
154
155
156 @Benchmark
157 public int baseline() {
158 return value;
159 }
160
161
162
163
164
165
166
167 @Benchmark
168 public int sample(Sources sources) {
169 return sources.getSampler().sample();
170 }
171 }