ClassValue perf?
Remi Forax
forax at univ-mlv.fr
Sun May 3 09:10:42 UTC 2015
Hi Peter,
computeValue() may recursively call get() by example to crawle the
inheritance hierarchy so i am not sure a lock is a good idea here
because in that case, it usually takes several millis to complete the to
level computeValue.
regards,
Rémi
On 05/03/2015 12:32 AM, Peter Levart wrote:
> Hi,
>
> I have considered using ClassValue in the past because it is quite
> fast (as fast as a hash table can be) but was afraid of footprint
> overhead, because I saw with debugger a structure being grown before
> my eyes that was quite complicated and that I could not understand
> entirely. Now I took some time to actually try to understand and
> measure it. In a typical scenario ClassValue was designed for (initial
> capacity == 32), initializing for example 16 ClassValues x 1024
> Classes, jmap shows the following interesting entries which all amount
> to overhead (that's on 64bit JVM with compressed OOPS):
>
>
> num #instances #bytes class name
> ----------------------------------------------
> 1: 16384 655360 java.util.WeakHashMap$Entry
> 2: 16402 524864 java.lang.ClassValue$Entry
> 8: 1024 147456 [Ljava.util.WeakHashMap$Entry;
> 9: 1025 147480 [Ljava.lang.ClassValue$Entry;
> 13: 1024 65536 java.lang.ClassValue$ClassValueMap
> 17: 1024 32768 java.lang.ref.ReferenceQueue
> 21: 1024 16384 java.lang.ref.ReferenceQueue$Lock
> ----------------------------------------------
> Total: 1589848 (97 bytes/entry)
>
>
> ClassValueMap is a WeakHashMap subclass which contains an array of
> WeakHashMap$Entry objects. In addition it maintains a parallel "cache"
> array of ClassValue$Entry objects. Both of those entry objects are
> WeakReferences. It means that each (Class,ClassValue) pair needs 2
> WeakReferences (with additional fields) and 2 array slots to hold
> associated value.
>
> So I wondered, would it be possible to simplify CV and make it more
> straight-forward by taking away almost half of overhead to get this:
>
> num #instances #bytes class name
> ----------------------------------------------
> 1: 16384 655360 java.lang.ClassValue$Entry
> 7: 1024 147456 [Ljava.lang.ClassValue$Entry;
> 13: 1024 40960 java.lang.ClassValue$ClassValueMap
> 15: 1024 32768 java.lang.ref.ReferenceQueue
> 19: 1024 16384 java.lang.ref.ReferenceQueue$Lock
> ----------------------------------------------
> Total: 892928 (54 bytes/entry)
>
>
> I tried and came up with the following:
>
> http://cr.openjdk.java.net/~plevart/misc/ClassValue.Alternative/webrev.01/
>
> It was not easy to keep the performance approximately on the same
> level while re-designing the implementation. But I think I managed to
> get it to perform mostly the same for the fast-path case. This
> alternative implementation also guarantees that, unless remove() is
> used, computeValue() is called exactly once per (Class, ClassValue)
> pair. Original implementation explains that it can redundantly compute
> more than one value and then throw away all but one. This alternative
> implementation could easily be modified to do the same (using CAS
> instead of lock) if anyone is afraid of deadlocks.
>
> Here's a micro benchmark with results measuring original vs.
> alternative implementation. Attached results are for JDK9 on Intel i7
> / Linux box using 4 concurrent threads for tests:
>
> http://cr.openjdk.java.net/~plevart/misc/ClassValue.Alternative/ClassValueBench.java
>
>
> It would be interesting to see if and how it works for you too (just
> compile and prepend to bootclasspath).
>
> Regards, Peter
>
> On 04/30/2015 03:57 PM, Michael Haupt wrote:
>> Hi,
>>
>> I'm looking at JDK-8031043 and would appreciate if you guys could
>> send any code you think might benefit from a smaller initial CV
>> memory footprint my way. Given what I've read, it could have some
>> impact during startup (Groovy?) if the value is reduced to 1.
>>
>> Best,
>>
>> Michael
>>
>>> Am 30.04.2015 um 15:43 schrieb Charles Oliver Nutter
>>> <headius at headius.com <mailto:headius at headius.com>>:
>>>
>>> On Mon, Apr 27, 2015 at 12:50 PM, Jochen Theodorou
>>> <blackdrag at gmx.org <mailto:blackdrag at gmx.org>> wrote:
>>>> Am 27.04.2015 19:17, schrieb Charles Oliver Nutter:
>>>>> Jochen: Is your class-to-metaclass map usable apart from the Groovy
>>>>> codebase?
>>>>
>>>>
>>>> Yes. Look for
>>>> org.codehaus.groovy.reflection.GroovyClassValuePreJava7 which
>>>> is normally wrapped by a factory.
>>>
>>> Excellent, thank you!
>>>
>>> - Charlie
>>
>>
>> --
>>
>> Oracle <http://www.oracle.com/>
>> Dr. Michael Haupt | Principal Member of Technical Staff
>> Phone: +49 331 200 7277 | Fax: +49 331 200 7561
>> OracleJava Platform Group | HotSpot Compiler Team
>> Oracle Deutschland B.V. & Co. KG, Schiffbauergasse 14 | 14467
>> Potsdam, Germany
>> Green Oracle <http://www.oracle.com/commitment> Oracle is committed
>> to developing practices and products that help protect the environment
>>
>>
>>
>>
>> _______________________________________________
>> mlvm-dev mailing list
>> mlvm-dev at openjdk.java.net
>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
>
>
>
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20150503/f64e72c9/attachment-0001.html>
More information about the mlvm-dev
mailing list