[PATCH] Some improvements for java.lang.Class

Сергей Цыпанов sergei.tsypanov at yandex.ru
Mon Mar 18 19:09:26 UTC 2019


Hi,

I have an enhancement proposal for java.lang.Class.methodToString and java.lang.Class.getTypeName.

First one is used when NoSuchMethodException is thrown from Class::getMethod which is in turn widely used in Spring Framework and often throws.

In current implementation we have 2 major problems:

- we create stream for the case when argTypes is not null but empty (which happens e. g. when Class::getMethod is called without vararg and throws)
- we have torn StringBuilder::append chain

I’ve modified the method to skip creation of Stream for empty array and used separate StringBuilder for each case. Latter allowed to rid SB completely and use invokedynamic-based concatenation.

I’ve compared both approaches for 2 cases:

1) argTypes is empty
2) argTypes.length == 1


Benchmark                                                   Mode  Cnt     Score     Error   Units

methodToString_noArgs                                       avgt   25   170,986 ±   5,708   ns/op
methodToString_noArgs_patched                               avgt   25    26,883 ±   2,906   ns/op

methodToString_1arg                                         avgt   25   183,012 ±   0,701   ns/op
methodToString_1arg_patched                                 avgt   25   112,784 ±   0,920   ns/op

methodToString_noArgs:·gc.alloc.rate.norm                   avgt   25   881,600 ±   9,786    B/op
methodToString_noArgs_patched:·gc.alloc.rate.norm           avgt   25   128,000 ±   0,001    B/op

methodToString_1arg:·gc.alloc.rate.norm                     avgt   25   960,000 ±   0,001    B/op
methodToString_1arg_patched:·gc.alloc.rate.norm             avgt   25   552,000 ±   0,001    B/op


We have the same problem regarding misusage of StringBuilder in Class:: getTypeName:

StringBuilder sb = new StringBuilder();
sb.append(cl.getName());
for (int i = 0; i < dimensions; i++) {
    sb.append("[]");
}
return sb.toString();

I suggest to use String::repeat instead of the loop: this again allows to get rid of StringBuilder and replace mentioned code with

return cl.getName() + "[]".repeat(dimensions);

Here are benchmark results executed for type Object[].class:

                                          Mode  Cnt     Score     Error   Units
getTypeName_patched                       avgt   25    16,037 ±   0,431   ns/op
getTypeName_patched:·gc.alloc.rate.norm   avgt   25    64,000 ±   0,001    B/op

getTypeName                               avgt   25    34,274 ±   1,432   ns/op
getTypeName:·gc.alloc.rate.norm           avgt   25   152,000 ±   0,001    B/op


Regards,
Sergei Tsypanov
-------------- next part --------------
A non-text attachment was scrubbed...
Name: klass.patch
Type: text/x-diff
Size: 2028 bytes
Desc: not available
URL: <https://mail.openjdk.java.net/pipermail/core-libs-dev/attachments/20190318/71d6b6a0/klass.patch>


More information about the core-libs-dev mailing list