RFR: 8343559: Optimize Class.getMethod(String, Class<?>...) for methods with no-arg
jengebr
duke at openjdk.org
Wed Nov 6 15:36:28 UTC 2024
On Wed, 6 Nov 2024 14:15:42 GMT, jengebr <duke 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
> I have a patch trying to avoid MethodList allocation for getMethod lookup: [liachmodded at 789c72c](https://github.com/liachmodded/jdk/commit/789c72c4a258181f6fd7c75b9e2ad50b32d37982)
I would love this - the memory cost of `getMethod()` is surprisingly high.
> However, another approach is to update the cache for ReflectionData, so we compute a Map from name+parameter key to the most specific method, when we compute `getMethods()`. Note that if we cannot find the method in the immediately declared methods, we always have to explore all declared methods from superclasses and superinterfaces, which has the same cost as `getMethods()`.
I see the runtime advantage but am concerned by the memory usage. Our Spring + Tomcat applications would generate a rather large cache.
-------------
PR Comment: https://git.openjdk.org/jdk/pull/21929#issuecomment-2460087764
More information about the core-libs-dev
mailing list