Proposal: optimization of Map.copyOf and Collectors.toUnmodifiableMap

Peter Levart peter.levart at gmail.com
Fri Jun 22 16:51:31 UTC 2018


Hi Stuart,

Do you still fear that "single-threaded-object" idiom is not safe?

I would just like to comment on the last approach...

On 06/19/2018 07:01 PM, Peter Levart wrote:
> Here's another attempt that uses the same technique but relaxes the 
> possible concurrent source map scenario (where number of pairs emitted 
> by Map.forEach() doesn't agree with Map.size()):
>
> http://cr.openjdk.java.net/~plevart/jdk-dev/UnmodifiableMap_copyOf/webrev.03/ 
>
>
> The construction is moved entirely into a separate MapBuilder object. 
> The builder is used for Map.of(...) methods too.
>
> Here are the benchmark results that show improvements in every respect 
> touched by the patch:
>
> http://cr.openjdk.java.net/~plevart/jdk-dev/UnmodifiableMap_copyOf/UnmodifiableMapBench_results.txt 
>
>
> Here are the JMH benchmarks used to produce these results:
>
> http://cr.openjdk.java.net/~plevart/jdk-dev/UnmodifiableMap_copyOf/UnmodifiableMapCollectorBench.java 
>
> http://cr.openjdk.java.net/~plevart/jdk-dev/UnmodifiableMap_copyOf/UnmodifiableMapCopyOfBench.java 
>
> http://cr.openjdk.java.net/~plevart/jdk-dev/UnmodifiableMap_copyOf/UnmodifiableMapOfBench.java 
>
>
>
> So what do you think of this one?
>
> Regards, Peter 

When this is used to copy concurrently changing concurrent Map, it has 
approximately the same performance consequence as when using 
Map.entrySet().toArray(). Either logic uses the estimated size to 
pre-size the array, but when the size is a moving target, it fails, so 
it has to do another copy at the end. My approach uses the estimated 
size to collect elements into the ready-made hash-table. When it fails, 
it has to do another copy, but in general case when the estimate is 
correct, it doesn't need an intermediary representation in the form of 
array, so it can be more optimal.

Regards, Peter



More information about the core-libs-dev mailing list