Great effort. >From first glance: the hashCode and equals of MethodList use m.getParameterTypes() which is cloned. I'd rather pay the collision costs and rely on the default hashCode/equals of Method itself (hashCode ignores the parameters). Possibly hashCode can include the returnType but equals should be direct call to Method.equals.
Stanimir On Sun, Oct 26, 2014 at 10:25 PM, Peter Levart <[email protected]> wrote: > Hi all, > > I revamped the Class.getMethods() implementation so that it is faster for > common cases and O(n) at the same time, which makes Martin's test happy (at > least in part that measures getMethods() speed - the class loading / > linkage in VM is a separate issue). > > With the following test that loads all classes from rt.jar and calls > getMethods() on each of them: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/Class. > getMethods/GetAllRtMethods.java > > And system property 'sun.reflect.noCaches=true' (so that we exercise the > logic in every loop - not just 1st), original code prints: > > 19657 classes loaded in 1.987373401 seconds. > 494141 methods obtained in 1.02493941 seconds. > 494141 methods obtained in 0.905235658 seconds. > 494141 methods obtained in 0.914434303 seconds. > 494141 methods obtained in 0.887212805 seconds. > 494141 methods obtained in 0.888929483 seconds. > 494141 methods obtained in 0.883309141 seconds. > 494141 methods obtained in 0.88341098 seconds. > 494141 methods obtained in 0.897397146 seconds. > 494141 methods obtained in 0.885677466 seconds. > 494141 methods obtained in 0.895834176 seconds. > > Patched code does the same about 10% faster: > > 19657 classes loaded in 2.084409717 seconds. > 494124 methods obtained in 0.915928578 seconds. > 494124 methods obtained in 0.785342465 seconds. > 494124 methods obtained in 0.784852619 seconds. > 494124 methods obtained in 0.793450205 seconds. > 494124 methods obtained in 0.849915078 seconds. > 494124 methods obtained in 0.77835511 seconds. > 494124 methods obtained in 0.764144701 seconds. > 494124 methods obtained in 0.754122383 seconds. > 494124 methods obtained in 0.747961897 seconds. > 494124 methods obtained in 0.7489937 seconds. > > Martin's test prints on my computer with original code the following: > > Base class load time: 177.80 ms > getDeclaredMethods: Methods: 65521, Total time: 35.79 ms, Time per method: > 0.0005 ms > getMethods : Methods: 65530, Total time: 50.15 ms, Time per method: > 0.0008 ms > Derived class load time: 34015.70 ms > getDeclaredMethods: Methods: 65521, Total time: 33.82 ms, Time per method: > 0.0005 ms > getMethods : Methods: 65530, Total time: 8122.00 ms, Time per > method: 0.1239 ms > > And with patched code this: > > Base class load time: 157.16 ms > getDeclaredMethods: Methods: 65521, Total time: 65.77 ms, Time per method: > 0.0010 ms > getMethods : Methods: 65530, Total time: 44.64 ms, Time per method: > 0.0007 ms > Derived class load time: 33996.69 ms > getDeclaredMethods: Methods: 65521, Total time: 32.63 ms, Time per method: > 0.0005 ms > getMethods : Methods: 65530, Total time: 92.12 ms, Time per method: > 0.0014 ms > > > Here's a webrev of the patch: > > http://cr.openjdk.java.net/~plevart/jdk9-dev/Class.getMethods/webrev.01/ > > Patched code is simpler (65 lines gone) and I hope, easier to understand > and change (I think a change in spec is coming in JDK9 which will handle > abstract interface methods the same way as default, right Joel?) > > I also took the liberty to eliminate some redundant array and > Field/Method/Constructor copies. get[Method0,Field0,Counstuctor0] now > return 'root' objects. Copying is performed in methods that call them and > expose the objects to any code outside java.lang.Class. Also, findFields() > and findMethods() don't do copying of Field/Method objects themselves, but > rather live that to methods that call them. getInterfaces() method now > delegates to getInterfaces(boolean copyArray) so that internally, not array > copying is performed. > > All 55 java/lang/reflect jtreg tests pass with this patch. > > > Regards, Peter > >
