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.core;
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.OutputTimeUnit;
29
30 import java.util.concurrent.ThreadLocalRandom;
31 import java.util.concurrent.TimeUnit;
32
33
34
35
36
37 @BenchmarkMode(Mode.Throughput)
38 @OutputTimeUnit(TimeUnit.MICROSECONDS)
39 @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
40 @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
41 @State(Scope.Benchmark)
42 @Fork(value = 1, jvmArgs = { "-server", "-Xms128M", "-Xmx128M" })
43 public class FloatingPointGenerationPerformance {
44
45
46
47
48
49
50 @State(Scope.Benchmark)
51 public static class LongSource {
52
53 private long state = ThreadLocalRandom.current().nextLong();
54
55
56
57
58
59
60 public final long nextLong() {
61 long z = state += 0x9e3779b97f4a7c15L;
62 z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L;
63 z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL;
64 return z ^ (z >>> 31);
65 }
66
67
68
69
70
71
72
73
74 public final int nextInt() {
75 long z = state += 0x9e3779b97f4a7c15L;
76 z = (z ^ (z >>> 33)) * 0x62a9d9ed799705f5L;
77 return (int)(((z ^ (z >>> 28)) * 0xcb24d0a5c88c35b3L) >>> 32);
78 }
79 }
80
81
82
83
84
85
86
87 @Benchmark
88 public long nextDoubleBaseline(LongSource source) {
89 return source.nextLong();
90 }
91
92
93
94
95
96 @Benchmark
97 public double nextDoubleUsingBitsToDouble(LongSource source) {
98
99
100
101
102 return Double.longBitsToDouble(0x3ffL << 52 | source.nextLong() >>> 12) - 1.0;
103 }
104
105
106
107
108
109 @Benchmark
110 public double nextDoubleUsingMultiply52bits(LongSource source) {
111 return (source.nextLong() >>> 12) * 0x1.0p-52d;
112 }
113
114
115
116
117
118 @Benchmark
119 public double nextDoubleUsingMultiply53bits(LongSource source) {
120 return (source.nextLong() >>> 11) * 0x1.0p-53d;
121 }
122
123
124
125
126
127 @Benchmark
128 public int nextFloatBaseline(LongSource source) {
129 return source.nextInt();
130 }
131
132
133
134
135
136 @Benchmark
137 public float nextFloatUsingBitsToFloat(LongSource source) {
138
139
140
141
142 return Float.intBitsToFloat(0x7f << 23 | source.nextInt() >>> 9) - 1.0f;
143 }
144
145
146
147
148
149 @Benchmark
150 public float nextFloatUsingMultiply23bits(LongSource source) {
151 return (source.nextInt() >>> 9) * 0x1.0p-23f;
152 }
153
154
155
156
157
158 @Benchmark
159 public float nextFloatUsingMultiply24bits(LongSource source) {
160 return (source.nextInt() >>> 8) * 0x1.0p-24f;
161 }
162 }