RFR: 8330465: Stable Values and Collections (Internal)
Chen Liang
liach at openjdk.org
Tue May 14 14:14:25 UTC 2024
On Mon, 22 Apr 2024 16:16:39 GMT, Dan Heidinga <heidinga at openjdk.org> wrote:
>> # Stable Values & Collections (Internal)
>>
>> ## Summary
>> This PR proposes to introduce an internal _Stable Values & Collections_ API, which provides immutable value holders where elements are initialized _at most once_. Stable Values & Collections offer the performance and safety benefits of final fields while offering greater flexibility as to the timing of initialization.
>>
>> ## Goals
>> * Provide an easy and intuitive API to describe value holders that can change at most once.
>> * Decouple declaration from initialization without significant footprint or performance penalties.
>> * Reduce the amount of static initializer and/or field initialization code.
>> * Uphold integrity and consistency, even in a multi-threaded environment.
>>
>> For more details, see the draft JEP: https://openjdk.org/jeps/8312611
>>
>> ## Performance
>> Performance compared to instance variables using an `AtomicReference` and one protected by double-checked locking under concurrent access by 8 threads:
>>
>>
>> Benchmark Mode Cnt Score Error Units
>> StableBenchmark.instanceAtomic avgt 10 1.576 ? 0.052 ns/op
>> StableBenchmark.instanceDCL avgt 10 1.608 ? 0.059 ns/op
>> StableBenchmark.instanceStable avgt 10 0.979 ? 0.023 ns/op <- StableValue (~40% faster than DCL)
>>
>>
>> Performance compared to static variables protected by `AtomicReference`, class-holder idiom holder, and double-checked locking (8 threads):
>>
>>
>> Benchmark Mode Cnt Score Error Units
>> StableBenchmark.staticAtomic avgt 10 1.335 ? 0.056 ns/op
>> StableBenchmark.staticCHI avgt 10 0.623 ? 0.086 ns/op
>> StableBenchmark.staticDCL avgt 10 1.418 ? 0.171 ns/op
>> StableBenchmark.staticList avgt 10 0.617 ? 0.024 ns/op
>> StableBenchmark.staticStable avgt 10 0.604 ? 0.022 ns/op <- StableValue ( > 2x faster than `AtomicInteger` and DCL)
>>
>>
>> Performance for stable lists in both instance and static contexts whereby the sum of random contents is calculated for stable lists (which are thread-safe) compared to `ArrayList` instances (which are not thread-safe) (under single thread access):
>>
>>
>> Benchmark Mode Cnt Score Error Units
>> StableListSumBenchmark.instanceArrayList avgt 10 0.356 ? 0.005 ns/op
>> StableListSumBenchmark.instanceList avgt 10 0.373 ? 0.017 ns/op <- Stable list
>> StableListSumBenchmark.staticArrayList avgt 10 0.352 ? ...
>
> src/java.base/share/classes/jdk/internal/lang/StableValue.java line 130:
>
>> 128: * } else {
>> 129: * V newValue = supplier.get();
>> 130: * stable.setOrThrow(newValue);
>
> If ::computeIfUnset allows racy sets, then it isn't equivalent to this code as ::setOrThrow will throw on a race, correct?
Indeed, this if-else should be guarded by a synchronized block, except the lock is on the internal mutex which is not publicly exposed.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/18794#discussion_r1575101750
More information about the compiler-dev
mailing list