RFR: 8343559: Optimize Class.getMethod(String, Class<?>...) for methods with no-arg

jengebr duke at openjdk.org
Wed Nov 6 15:36:29 UTC 2024


On Wed, 6 Nov 2024 15:20:42 GMT, Chen Liang <liach at openjdk.org> wrote:

>> This change optimizes the runtime of `Class.getMethod(String, Class<?>[])` in two ways:
>> 
>> 1. While iterating across each Method to find a match (existing logic) it now compares parameter count before checking method name.  This check is substantially faster.
>> 2. While iterating (existing logic) if the requested method has no arguments, the loop terminates early after finding one match.  This works because there can only be one zero-arg method with the matching name in the specific class.
>> 
>> A benchmark and unit tests are included; benchmark results (below) show an improvement in all cases, and an especially large gain when the immediate class contains the no-arg target.
>> 
>> Base:
>> 
>> Benchmark                          Mode  Cnt     Score    Error  Units
>> ClassGetMethod.getConcreteFiveArg  avgt    6    90.866 ±  2.698  ns/op
>> ClassGetMethod.getConcreteNoArg    avgt    6    72.472 ± 10.225  ns/op
>> ClassGetMethod.getIntfFiveArg      avgt    6   198.524 ±  7.089  ns/op
>> ClassGetMethod.getIntfNoArg        avgt    6   191.739 ±  4.695  ns/op
>> ClassGetMethod.getNoSuchMethod     avgt   10  2254.308 ± 42.829  ns/op
>> ClassGetMethod.getSuperFiveArg     avgt    6   165.897 ±  4.370  ns/op
>> ClassGetMethod.getSuperNoArg       avgt    6   148.361 ±  4.573  ns/op
>> 
>> 
>> Modified:
>> 
>> Benchmark                          Mode  Cnt     Score    Error  Units
>> ClassGetMethod.getConcreteFiveArg  avgt    6    77.059 ±  2.644  ns/op
>> ClassGetMethod.getConcreteNoArg    avgt    6    47.666 ±  6.544  ns/op
>> ClassGetMethod.getIntfFiveArg      avgt    6   164.427 ±  4.356  ns/op
>> ClassGetMethod.getIntfNoArg        avgt    6   161.256 ±  6.832  ns/op
>> ClassGetMethod.getNoSuchMethod     avgt   10  2158.844 ± 43.716  ns/op
>> ClassGetMethod.getSuperFiveArg     avgt    6   129.047 ±  4.414  ns/op
>> ClassGetMethod.getSuperNoArg       avgt    6   123.728 ±  6.182  ns/op
>
> src/java.base/share/classes/java/lang/PublicMethods.java line 157:
> 
>> 155:                         head = tail = new MethodList(method);
>> 156:                         if (ptypes.length == 0) {
>> 157:                             // zero args can only have one match - stop looking
> 
> This is wrong: if superclass has `Object work()` and this class has `Integer work()`, bytecode for this class will have a synthetic final `Object work()` that delegates call to `Integer work()`.

Gotcha, I'll remove the no-arg change.  Thanks!

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

PR Review Comment: https://git.openjdk.org/jdk/pull/21929#discussion_r1831250497


More information about the core-libs-dev mailing list