RFR: 8332842: Optimize empty CopyOnWriteArrayList allocations [v3]

jengebr duke at openjdk.org
Thu Jun 20 19:20:12 UTC 2024


On Thu, 6 Jun 2024 12:46:36 GMT, jengebr <duke at openjdk.org> wrote:

>> Improve `java/util/concurrent/CopyOnWriteArrayList` by eliminating needless cloning of Object[0] instances. This cloning is intended to prevent callers from changing array contents, but many `CopyOnWriteArrayList`s are allocated to size zero, or are otherwise maintained empty, so cloning is unnecessary.
>> 
>> Results from the included JMH benchmark:
>> Before:
>> 
>> Benchmark                                                    Mode  Cnt   Score   Error  Units
>> CopyOnWriteArrayListBenchmark.clear                          avgt    5  74.487 ± 1.793  ns/op
>> CopyOnWriteArrayListBenchmark.clearEmpty                     avgt    5  27.918 ± 0.759  ns/op
>> CopyOnWriteArrayListBenchmark.createInstanceArray            avgt    5  16.656 ± 0.375  ns/op
>> CopyOnWriteArrayListBenchmark.createInstanceArrayEmpty       avgt    5  15.415 ± 0.489  ns/op
>> CopyOnWriteArrayListBenchmark.createInstanceCollection       avgt    5  21.608 ± 0.363  ns/op
>> CopyOnWriteArrayListBenchmark.createInstanceCollectionEmpty  avgt    5  15.374 ± 0.260  ns/op
>> CopyOnWriteArrayListBenchmark.createInstanceDefault          avgt    5  15.688 ± 0.350  ns/op
>> CopyOnWriteArrayListBenchmark.readInstance                   avgt   10  2625.125 ± 71.802  ns/op
>> CopyOnWriteArrayListBenchmark.readInstanceEmpty              avgt   10  2607.447 ± 46.400  ns/op
>> 
>> 
>> After:
>> 
>> Benchmark                                                    Mode  Cnt   Score   Error  Units
>> CopyOnWriteArrayListBenchmark.clear                          avgt    5  75.365 ± 2.092  ns/op
>> CopyOnWriteArrayListBenchmark.clearEmpty                     avgt    5  20.803 ± 0.539  ns/op
>> CopyOnWriteArrayListBenchmark.createInstanceArray            avgt    5  16.808 ± 0.582  ns/op
>> CopyOnWriteArrayListBenchmark.createInstanceArrayEmpty       avgt    5  12.980 ± 0.418  ns/op
>> CopyOnWriteArrayListBenchmark.createInstanceCollection       avgt    5  21.627 ± 0.173  ns/op
>> CopyOnWriteArrayListBenchmark.createInstanceCollectionEmpty  avgt    5  12.864 ± 0.408  ns/op
>> CopyOnWriteArrayListBenchmark.createInstanceDefault          avgt    5  12.931 ± 0.255  ns/op
>> CopyOnWriteArrayListBenchmark.readInstance                   avgt   10  2615.500 ± 30.771  ns/op
>> CopyOnWriteArrayListBenchmark.readInstanceEmpty              avgt   10  2583.892 ± 62.086  ns/op
>
> jengebr has updated the pull request incrementally with one additional commit since the last revision:
> 
>   Adding benchmarks for readObject

Thank you!  I've expanded coverage to remove(int) as well.

> One thing that surprises me is the change to remove(Object) to handle the case where the last remaining element is removed. Does that help the application that prompted this change? Part of me wonders if remove(int) needs to do the same as someone will show up sometime to ask.

The application benefits most from the lower footprint of the empty constructors, but I tried to expand the optimization throughout the class.  Clearly I missed a spot, thank you for catching it.

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

PR Comment: https://git.openjdk.org/jdk/pull/19527#issuecomment-2181366938


More information about the core-libs-dev mailing list