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