On Feb 14 2013, at 05:24 , Peter Levart wrote:

> Hello Mike,
> 
> On 02/13/2013 09:21 PM, Mike Duigou wrote:
>> This looks like excellent contribution Peter!
>> 
>> I will proceed with the testing needed to integrate your improved 
>> toArray()/toArray(T[]) implementations. I have created an issue, 
>> JDK-8008167, for this patch.
>> 
>> I am surprised that this didn't get more attention back in December as it 
>> does seem to offer significant benefits for size and performance.
> 
> It would if IdentityHashMap was used instead of HashMap for annotations 
> caching. But that's something that should be done on the global basis (there 
> are various places where Maps of annotations are constructed: reflection 
> classes, AnnotationParser, ...).
> 
> There's also opportunity to use IdentityHashMap instead of LinkedHashMap 
> (totally unnecessary, since it is never iterated !!??) for holding member 
> values of annotation instances (the Map is keyed by String objects, but they 
> could be interned at map creation time - the same string values are interned 
> already, since they are equal to names of methods of the annotation 
> interfaces and retrieval is already using the interned Strings: 
> Method.getName() - see AnnotationInvocationHandler)...
> 
> Let me know if testing finds anything or if there's anything I can do 
> (regarding coding style, etc).

I have made the style changes (method brackets placement, while->for) suggested 
by Martin but didn't make any other changes.

Build farm regression testing passed with flying colours so I will integrate 
the patch today.

I encourage you to pursue the replacement of LinkedHashMap and HashMap with 
IdentityHashMap for annotations.

Mike

> 
> Regards, Peter
> 
>> 
>> Thanks,
>> 
>> Mike
>>  On Dec 12 2012, at 01:07 , Peter Levart wrote:
>> 
>>> Hi all,
>>> 
>>> I propose a patch to java.util.IdentityHashMap to speed-up toArray methods 
>>> of it's keySet, values and entrySet views:
>>> 
>>> http://dl.dropbox.com/u/101777488/jdk8-tl/IdentityHashMap/webrev.01/index.html
>>> 
>>> I toyed with the possibility to replace HashMap-s, that are used in 
>>> java.lang.Class and java.lang.reflect.[Field|Method|Constructor] to hold 
>>> cached annotations, with IdentityHashMap-s. They are a perfect replacement, 
>>> since keys in these maps are java.lang.Class objects.
>>> 
>>> They are more compact then HashMap-s. This is the comparison of allocated 
>>> heap bytes between HashMap and IdentityHashMap for various sizes and 
>>> corresponding capacities which takes into account the size of the Map 
>>> object, the size of allocated array and the size of Map.Entry-s in case of 
>>> HM (IHM doesn't have them) and the size of associated values Collection 
>>> view (allocated when dumping annotations to array). HM-s for annotations 
>>> are currently allocated with default initial capacity (16). I propose to 
>>> allocate IHM-s with initial capacity 8 that fits to hold 5 entries which is 
>>> enough for typical annotation use cases on one hand and still makes 
>>> improvement for any case on the other:
>>> 
>>> 32 bit JVM:
>>> 
>>>        |     HashMap     | IdentityHashMap |
>>>    size|capacity    bytes|capacity    bytes|IHM.bytes-HM.bytes
>>> --------+-----------------+-----------------+------------------
>>>       0|      16      144|       8      136|      -8
>>>       1|      16      168|       8      136|     -32
>>>       2|      16      192|       8      136|     -56
>>>       3|      16      216|       8      136|     -80
>>>       4|      16      240|       8      136|    -104
>>>       5|      16      264|       8      136|    -128
>>>       6|      16      288|      16      200|     -88
>>>       7|      16      312|      16      200|    -112
>>>       8|      16      336|      16      200|    -136
>>>       9|      16      360|      16      200|    -160
>>>      10|      16      384|      16      200|    -184
>>>      11|      16      408|      16      200|    -208
>>>      12|      16      432|      32      328|    -104
>>>      13|      32      520|      32      328|    -192
>>>      14|      32      544|      32      328|    -216
>>>      15|      32      568|      32      328|    -240
>>>      16|      32      592|      32      328|    -264
>>>      17|      32      616|      32      328|    -288
>>>      18|      32      640|      32      328|    -312
>>>      19|      32      664|      32      328|    -336
>>>      20|      32      688|      32      328|    -360
>>>      40|      64     1296|      64      584|    -712
>>>      60|     128     2032|     128     1096|    -936
>>>      80|     128     2512|     128     1096|   -1416
>>>     100|     256     3504|     256     2120|   -1384
>>>     120|     256     3984|     256     2120|   -1864
>>>     140|     256     4464|     256     2120|   -2344
>>>     160|     256     4944|     256     2120|   -2824
>>>     180|     256     5424|     512     4168|   -1256
>>> 
>>> 64 bit JVM:
>>> 
>>>        |     HashMap     | IdentityHashMap |
>>>    size|capacity    bytes|capacity    bytes|IHM.bytes-HM.bytes
>>> --------+-----------------+-----------------+------------------
>>>       0|      16      248|       8      240|      -8
>>>       1|      16      296|       8      240|     -56
>>>       2|      16      344|       8      240|    -104
>>>       3|      16      392|       8      240|    -152
>>>       4|      16      440|       8      240|    -200
>>>       5|      16      488|       8      240|    -248
>>>       6|      16      536|      16      368|    -168
>>>       7|      16      584|      16      368|    -216
>>>       8|      16      632|      16      368|    -264
>>>       9|      16      680|      16      368|    -312
>>>      10|      16      728|      16      368|    -360
>>>      11|      16      776|      16      368|    -408
>>>      12|      16      824|      32      624|    -200
>>>      13|      32     1000|      32      624|    -376
>>>      14|      32     1048|      32      624|    -424
>>>      15|      32     1096|      32      624|    -472
>>>      16|      32     1144|      32      624|    -520
>>>      17|      32     1192|      32      624|    -568
>>>      18|      32     1240|      32      624|    -616
>>>      19|      32     1288|      32      624|    -664
>>>      20|      32     1336|      32      624|    -712
>>>      40|      64     2552|      64     1136|   -1416
>>>      60|     128     4024|     128     2160|   -1864
>>>      80|     128     4984|     128     2160|   -2824
>>>     100|     256     6968|     256     4208|   -2760
>>>     120|     256     7928|     256     4208|   -3720
>>>     140|     256     8888|     256     4208|   -4680
>>>     160|     256     9848|     256     4208|   -5640
>>>     180|     256    10808|     512     8304|   -2504
>>> 
>>> I hope I've got that tables right. This is the program to compute them:
>>> 
>>> https://raw.github.com/plevart/jdk8-tl/JEP-149.2/test/src/test/IHMvsHMsizes.java
>>> 
>>> IHM is also more performant when retrieving the values by keys. The only 
>>> area in which it lags behind HashMap and is important for accessing 
>>> annotations in bulk is the toArray method of the values view. In particular 
>>> for small sizes. The above patch speeds-up those methods by using index 
>>> iteration instead of Iterator.
>>> 
>>> Here are some speed-up comparisons:
>>> 
>>> https://raw.github.com/plevart/jdk8-tl/JEP-149.2/test/IHM_benchmark_results_i7-2600K.txt
>>> 
>>> They are obtained by running the following micro benchmark:
>>> 
>>> https://raw.github.com/plevart/jdk8-tl/JEP-149.2/test/src/test/IdentityHashMapTest.java
>>> 
>>> Even if IHM doesn't replace HM for holding annotations, a speed-up 
>>> improvement is an improvement.
>>> 
>>> 
>>> Regards, Peter
>>> 
> 

Reply via email to