|
29 | 29 | import org.openjdk.jmh.annotations.*; |
30 | 30 | import org.openjdk.jmh.infra.Blackhole; |
31 | 31 |
|
| 32 | +import static java.lang.ScopedValue.where; |
32 | 33 | import static org.openjdk.bench.java.lang.ScopedValuesData.*; |
33 | 34 |
|
34 | 35 | /** |
@@ -102,6 +103,26 @@ public int thousandMaybeGets(Blackhole bh) throws Exception { |
102 | 103 | return result; |
103 | 104 | } |
104 | 105 |
|
| 106 | + @Benchmark |
| 107 | + @OutputTimeUnit(TimeUnit.NANOSECONDS) |
| 108 | + public int thousandUnboundOrElses(Blackhole bh) throws Exception { |
| 109 | + int result = 0; |
| 110 | + for (int i = 0; i < 1_000; i++) { |
| 111 | + result += ScopedValuesData.unbound.orElse(1); |
| 112 | + } |
| 113 | + return result; |
| 114 | + } |
| 115 | + |
| 116 | + @Benchmark |
| 117 | + @OutputTimeUnit(TimeUnit.NANOSECONDS) |
| 118 | + public int thousandBoundOrElses(Blackhole bh) throws Exception { |
| 119 | + int result = 0; |
| 120 | + for (int i = 0; i < 1_000; i++) { |
| 121 | + result += ScopedValuesData.sl1.orElse(1); |
| 122 | + } |
| 123 | + return result; |
| 124 | + } |
| 125 | + |
105 | 126 | // Test 2: stress the ScopedValue cache. |
106 | 127 | // The idea here is to use a bunch of bound values cyclically, which |
107 | 128 | // stresses the ScopedValue cache. |
@@ -137,12 +158,12 @@ public int sixValues_ThreadLocal() throws Exception { |
137 | 158 | @Benchmark |
138 | 159 | @OutputTimeUnit(TimeUnit.NANOSECONDS) |
139 | 160 | public int CreateBindThenGetThenRemove_ScopedValue() throws Exception { |
140 | | - return ScopedValue.where(sl1, THE_ANSWER).call(sl1::get); |
| 161 | + return where(sl1, THE_ANSWER).call(sl1::get); |
141 | 162 | } |
142 | 163 |
|
143 | 164 |
|
144 | 165 | // Create a Carrier ahead of time: might be slightly faster |
145 | | - private static final ScopedValue.Carrier HOLD_42 = ScopedValue.where(sl1, 42); |
| 166 | + private static final ScopedValue.Carrier HOLD_42 = where(sl1, 42); |
146 | 167 | @Benchmark |
147 | 168 | @OutputTimeUnit(TimeUnit.NANOSECONDS) |
148 | 169 | public int bindThenGetThenRemove_ScopedValue() throws Exception { |
@@ -230,4 +251,65 @@ public Object newInstance() { |
230 | 251 | ScopedValue<Integer> val = ScopedValue.newInstance(); |
231 | 252 | return val; |
232 | 253 | } |
| 254 | + |
| 255 | + // Test 6: Performance with a large number of bindings |
| 256 | + static final long deepCall(ScopedValue<Integer> outer, long n) { |
| 257 | + long result = 0; |
| 258 | + if (n > 0) { |
| 259 | + ScopedValue<Long> sv = ScopedValue.newInstance(); |
| 260 | + return where(sv, n).call(() -> deepCall(outer, n - 1)); |
| 261 | + } else { |
| 262 | + for (int i = 0; i < 1_000_000; i++) { |
| 263 | + result += outer.orElse(12); |
| 264 | + } |
| 265 | + } |
| 266 | + return result; |
| 267 | + } |
| 268 | + |
| 269 | + @Benchmark |
| 270 | + @OutputTimeUnit(TimeUnit.MILLISECONDS) |
| 271 | + public long deepBindingTest1() { |
| 272 | + return deepCall(ScopedValuesData.unbound, 1000); |
| 273 | + } |
| 274 | + |
| 275 | + @Benchmark |
| 276 | + @OutputTimeUnit(TimeUnit.MILLISECONDS) |
| 277 | + public long deepBindingTest2() { |
| 278 | + return deepCall(ScopedValuesData.sl1, 1000); |
| 279 | + } |
| 280 | + |
| 281 | + |
| 282 | + // Test 7: Performance with a large number of bindings |
| 283 | + // Different from Test 6 in that we recursively build a very long |
| 284 | + // list of Carriers and invoke Carrier.call() only once. |
| 285 | + static final long deepCall2(ScopedValue<Integer> outer, ScopedValue.Carrier carrier, long n) { |
| 286 | + long result = 0; |
| 287 | + if (n > 0) { |
| 288 | + ScopedValue<Long> sv = ScopedValue.newInstance(); |
| 289 | + return deepCall2(outer, carrier.where(sv, n), n - 1); |
| 290 | + } else { |
| 291 | + result = carrier.call(() -> { |
| 292 | + long sum = 0; |
| 293 | + for (int i = 0; i < 1_000_000; i++) { |
| 294 | + sum += outer.orElse(12); |
| 295 | + } |
| 296 | + return sum; |
| 297 | + }); |
| 298 | + } |
| 299 | + return result; |
| 300 | + } |
| 301 | + |
| 302 | + @Benchmark |
| 303 | + @OutputTimeUnit(TimeUnit.MILLISECONDS) |
| 304 | + public long deepBindingTest3() { |
| 305 | + return deepCall2(ScopedValuesData.unbound, where(ScopedValuesData.sl2,0), 1000); |
| 306 | + } |
| 307 | + |
| 308 | + @Benchmark |
| 309 | + @OutputTimeUnit(TimeUnit.MILLISECONDS) |
| 310 | + public long deepBindingTest4() { |
| 311 | + return deepCall2(ScopedValuesData.sl1, where(ScopedValuesData.sl2, 0), 1000); |
| 312 | + } |
| 313 | + |
| 314 | + |
233 | 315 | } |
0 commit comments