On Fri, 27 Dec 2024 23:24:46 GMT, Chen Liang <li...@openjdk.org> wrote:

>>> For sure we should use result of `putIfAbsent`
>> 
>> Drive-by comment...
>> 
>> From what i can infer, the performance regression being addressed here is 
>> caused in part by the fact that (for example) 
>> `ConcurrentHashMap.computeIfAbsent()` provides an atomicity guarantee, which 
>> is a stronger requirement than is necessary here, and therefore by splitting 
>> up that call up into two separate, non-atomic `get()` and `put()` calls we 
>> get (counter-intuitively) faster execution time, even though there are more 
>> lines of code. Note `putIfAbsent()` also guarantees atomicity, so the same 
>> problem of slowness caused by "unnecessary atomicity" might occur with it as 
>> well.
>
> Indeed, just noticed that both `computeIfAbsent` and `putIfAbsent` may 
> acquire the lock when the key is present, while `get` never acquires a lock 
> for read-only access.
> 
> Maybe the implementation was written back when locking was less costly (with 
> biased locking, etc.). Now we might have to reconsider locking until we know 
> for sure a plain get fails.

This scenario is discussed in Effective Java by Joshua Block. His observation 
then (java 5/6 time frame?) was optimistically calling `get` first and only 
calling `putIfAbsent` or `computeIfAbsent` if the `get` returned `null` was 
250% faster, and this is because calls to put/compute ifAbsent have contention. 
There have been changes made to those methods since then to try to avoid 
synchronization when the key is already present, but the observation seems to 
confirm that the optimistic `get` call first is still faster (though a much 
smaller difference).

My comment was not to revert back to the prior change of just calling 
`computeIfAbsent`, but rather just to change the (expected rare) case when the 
first `get` returns `null` to replace the `putIfAbsent` and second `get` call 
with a single `computeIfAbsent` (or utilize the result of `putIfAbsent` to 
avoid the second call to `get`).

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

PR Review Comment: https://git.openjdk.org/jdk/pull/22854#discussion_r1899699668

Reply via email to