jqwik-team / jqwik

Property-Based Testing on the JUnit Platform
http://jqwik.net
Eclipse Public License 2.0
578 stars 64 forks source link

Cache LifecycleMethods results: findBeforeTryMethods, findAfterTryMethods, etc #429

Closed vlsi closed 1 year ago

vlsi commented 1 year ago

Testing Problem

LifecycleMethods consumes significant CPU time performing the same reflective lookup.

Suggested Solution

Cache the results via https://docs.oracle.com/javase/7/docs/api/java/lang/ClassValue.html or something like that.

Profiling results

Allocation:

allocation profiling of LifecycleMethods

CPU:

CPU profiling of LifecycleMethods
vlsi commented 1 year ago

Sample fix:

+       private static final ClassValue<List<Method>> findBeforeTryMethods = new ClassValue<List<Method>>() {
+               @Override
+               protected List<Method> computeValue(Class<?> testClass) {
+                       return findMethods(testClass, false, true, BeforeTry.class, HierarchyTraversalMode.TOP_DOWN);
+               }
+       };
+
        static List<Method> findBeforeTryMethods(Class<?> testClass) {
-               return findMethods(testClass, false, true, BeforeTry.class, HierarchyTraversalMode.TOP_DOWN);
+               return findBeforeTryMethods.get(testClass);
        }

+       private static final ClassValue<List<Method>> findAfterTryMethods = new ClassValue<List<Method>>() {
+               @Override
+               protected List<Method> computeValue(Class<?> testClass) {
+                       return findMethods(testClass, false, true, AfterTry.class, HierarchyTraversalMode.BOTTOM_UP);
+               }
+       };
+
        static List<Method> findAfterTryMethods(Class<?> testClass) {
-               return findMethods(testClass, false, true, AfterTry.class, HierarchyTraversalMode.BOTTOM_UP);
+               return findAfterTryMethods.get(testClass);
        }

WDYT?

It improves shrink time from ~60s to 30sec for case like https://github.com/jlink/jqwik/issues/428#issue-1492125145 (increasing .withMaxTransformations(12) makes the case WAY longer to execute)