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.core;
19
20 import org.apache.commons.rng.UniformRandomProvider;
21 import org.apache.commons.rng.simple.RandomSource;
22 import org.openjdk.jmh.annotations.Level;
23 import org.openjdk.jmh.annotations.Param;
24 import org.openjdk.jmh.annotations.Scope;
25 import org.openjdk.jmh.annotations.Setup;
26 import org.openjdk.jmh.annotations.State;
27
28 /**
29 * A benchmark state that can retrieve the various generators defined by {@link RandomSource}
30 * values.
31 *
32 * <p>The state will include only those that do not require additional constructor arguments.</p>
33 *
34 * <p>This class is abstract since it adds a special {@code RandomSource} named
35 * {@code BASELINE}. A baseline implementation for the {@link UniformRandomProvider}
36 * interface must be provided by implementing classes. For example to baseline methods
37 * using {@link UniformRandomProvider#nextInt()} use the following code:</p>
38 *
39 * <pre>
40 * @State(Scope.Benchmark)
41 * public static class Sources extends BaselineSources {
42 * @Override
43 * protected UniformRandomProvider createBaseline() {
44 * return BaselineUtils.getNextInt();
45 * }
46 * }
47 * </pre>
48 *
49 * <p>Note: It is left to the implementation to ensure the baseline is suitable for the method
50 * being tested.</p>
51 */
52 @State(Scope.Benchmark)
53 public abstract class BaselineSources {
54 /** The keyword identifying the baseline implementation. */
55 private static final String BASELINE = "BASELINE";
56
57 /**
58 * RNG providers.
59 *
60 * <p>List all providers that do not require additional constructor arguments. This list
61 * is in the declared order of {@link RandomSource}.</p>
62 */
63 @Param({BASELINE,
64 "JDK",
65 "WELL_512_A",
66 "WELL_1024_A",
67 "WELL_19937_A",
68 "WELL_19937_C",
69 "WELL_44497_A",
70 "WELL_44497_B",
71 "MT",
72 "ISAAC",
73 "SPLIT_MIX_64",
74 "XOR_SHIFT_1024_S",
75 "TWO_CMRES",
76 "MT_64",
77 "MWC_256",
78 "KISS",
79 "XOR_SHIFT_1024_S_PHI",
80 "XO_RO_SHI_RO_64_S",
81 "XO_RO_SHI_RO_64_SS",
82 "XO_SHI_RO_128_PLUS",
83 "XO_SHI_RO_128_SS",
84 "XO_RO_SHI_RO_128_PLUS",
85 "XO_RO_SHI_RO_128_SS",
86 "XO_SHI_RO_256_PLUS",
87 "XO_SHI_RO_256_SS",
88 "XO_SHI_RO_512_PLUS",
89 "XO_SHI_RO_512_SS",
90 "PCG_XSH_RR_32",
91 "PCG_XSH_RS_32",
92 "PCG_RXS_M_XS_64",
93 "PCG_MCG_XSH_RR_32",
94 "PCG_MCG_XSH_RS_32",
95 "MSWS",
96 "SFC_32",
97 "SFC_64",
98 "JSF_32",
99 "JSF_64",
100 "XO_SHI_RO_128_PP",
101 "XO_RO_SHI_RO_128_PP",
102 "XO_SHI_RO_256_PP",
103 "XO_SHI_RO_512_PP",
104 "XO_RO_SHI_RO_1024_PP",
105 "XO_RO_SHI_RO_1024_S",
106 "XO_RO_SHI_RO_1024_SS",
107 "PCG_XSH_RR_32_OS",
108 "PCG_XSH_RS_32_OS",
109 "PCG_RXS_M_XS_64_OS",
110 "L64_X128_SS",
111 "L64_X128_MIX",
112 "L64_X256_MIX",
113 "L64_X1024_MIX",
114 "L128_X128_MIX",
115 "L128_X256_MIX",
116 "L128_X1024_MIX",
117 "L32_X64_MIX"})
118 private String randomSourceName;
119
120 /** RNG. */
121 private UniformRandomProvider provider;
122
123 /**
124 * Gets the generator.
125 *
126 * @return the RNG.
127 */
128 public UniformRandomProvider getGenerator() {
129 return provider;
130 }
131
132 /** Instantiates generator. This need only be done once per set of iterations. */
133 @Setup(Level.Trial)
134 public void setup() {
135 if (BASELINE.equals(randomSourceName)) {
136 provider = createBaseline();
137 } else {
138 final RandomSource randomSource = RandomSource.valueOf(randomSourceName);
139 provider = randomSource.create();
140 }
141 }
142
143 /**
144 * Creates the baseline {@link UniformRandomProvider}.
145 *
146 * <p>This should implement the method(s) that will be tested. The speed of this RNG is expected
147 * to create a baseline against which all other generators will be compared.</p>
148 *
149 * @return the baseline RNG.
150 */
151 protected abstract UniformRandomProvider createBaseline();
152 }