On Tue, 11 Nov 2025 16:48:58 GMT, Jorn Vernee <[email protected]> wrote:

>> I've added two new benchmarks:
>> 
>> 
>>     private static final LazyConstant<Optional<Integer>> OPTIONAL_42 = 
>> LazyConstant.of(() -> Optional.of(42));
>>     private static final LazyConstant<Optional<Integer>> OPTIONAL_42_2 = 
>> LazyConstant.of(() -> Optional.of(42));
>>     private static final LazyConstant<Optional<Integer>> OPTIONAL_EMPTY = 
>> LazyConstant.of(Optional::empty);
>>     private static final LazyConstant<Optional<Integer>> OPTIONAL_EMPTY2 = 
>> LazyConstant.of(Optional::empty);
>>     
>>     ...
>>     
>>         @Benchmark
>>     public int staticOptional42() {
>>         return OPTIONAL_42.get().orElseThrow() + 
>> OPTIONAL_42_2.get().orElseThrow();
>>     }
>> 
>>     @Benchmark
>>     public boolean staticOptionalEmpty() {
>>         return OPTIONAL_EMPTY.get().isEmpty() ^ 
>> OPTIONAL_EMPTY2.get().isEmpty();
>>     }
>> 
>>     
>> 
>> 
>> Which gives:
>> 
>> 
>> Benchmark                              Mode  Cnt  Score   Error  Units
>> StableValueBenchmark.staticOptional42  avgt   10  0.354 ± 0.045  ns/op
>> 
>> Benchmark                                 Mode  Cnt  Score   Error  Units
>> StableValueBenchmark.staticOptionalEmpty  avgt   10  0.370 ± 0.030  ns/op
>> 
>> 
>> So, both `Optional` variants appears to support constant folding.
>
> I don't think we can drawn that conclusion just based on the speed. For the 
> non-constant folded cases, this would be 2 loads and an xor.
> 
> I don't see how C2 would be allowed to constant fold the loads if the value 
> is `null`, since that's explicitly forbidden by `@Stable` (and there's no 
> easy way around that AFAIK, since the JIT thread may see a partially 
> initialized object, so it conservatively ignores default values).

Yes. I think you are right @JornVernee. I've explored several ways to fix this 
and the simplest one might be to have a sentinel value instead of `null` to 
flag emptiness. Splitting the class into a bimorphic implementation would not 
be good for `value` classes (at least not for now), even though the C2 might 
otherwise be able to optimize the two variants.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/27605#discussion_r2527523848

Reply via email to