You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by ta...@apache.org on 2026/07/24 13:25:19 UTC

(openwebbeans) 03/04: bucket getFilteredMethods override check by method name to avoid O(n^2) scan

This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch startupperf
in repository https://gitbox.apache.org/repos/asf/openwebbeans.git

commit d4ab1dedb56f66a0da20c90b09437f0e8e90d868
Author: tandraschko <ta...@apache.org>
AuthorDate: Fri Jul 24 15:22:24 2026 +0200

    bucket getFilteredMethods override check by method name to avoid O(n^2) scan
---
 .../webbeans/portable/AnnotatedElementFactory.java | 25 ++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/webbeans-impl/src/main/java/org/apache/webbeans/portable/AnnotatedElementFactory.java b/webbeans-impl/src/main/java/org/apache/webbeans/portable/AnnotatedElementFactory.java
index af02078b8..0788d7021 100644
--- a/webbeans-impl/src/main/java/org/apache/webbeans/portable/AnnotatedElementFactory.java
+++ b/webbeans-impl/src/main/java/org/apache/webbeans/portable/AnnotatedElementFactory.java
@@ -21,8 +21,12 @@ package org.apache.webbeans.portable;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
@@ -327,7 +331,7 @@ public final class AnnotatedElementFactory
         }
         methods = Collections.unmodifiableSet(getFilteredMethods(annotatedType.getJavaClass(),
                                                                  (Set)annotatedType.getMethods(),
-            new HashSet<>()));
+            new HashSet<>(), new HashMap<>()));
         Set<AnnotatedMethod<?>> old = annotatedMethodsOfTypeCache.putIfAbsent(annotatedType, methods);
         if (old != null)
         {
@@ -354,7 +358,8 @@ public final class AnnotatedElementFactory
         annotatedMethodsOfTypeCache.clear();
     }
     
-    private Set<? extends AnnotatedMethod<?>> getFilteredMethods(Class<?> type, Set<AnnotatedMethod<?>> allMethods, Set<AnnotatedMethod<?>> filteredMethods)
+    private Set<? extends AnnotatedMethod<?>> getFilteredMethods(Class<?> type, Set<AnnotatedMethod<?>> allMethods,
+            Set<AnnotatedMethod<?>> filteredMethods, Map<String, List<AnnotatedMethod<?>>> filteredByName)
     {
         if (type == null)
         {
@@ -362,17 +367,25 @@ public final class AnnotatedElementFactory
         }
         for (AnnotatedMethod<?> annotatedMethod: allMethods)
         {
-            if (annotatedMethod.getJavaMember().getDeclaringClass() == type && !isOverridden(annotatedMethod, filteredMethods))
+            if (annotatedMethod.getJavaMember().getDeclaringClass() == type && !isOverridden(annotatedMethod, filteredByName))
             {
                 filteredMethods.add(annotatedMethod);
+                filteredByName.computeIfAbsent(annotatedMethod.getJavaMember().getName(), k -> new ArrayList<>(2))
+                    .add(annotatedMethod);
             }
         }
-        return getFilteredMethods(type.getSuperclass(), allMethods, filteredMethods);
+        return getFilteredMethods(type.getSuperclass(), allMethods, filteredMethods, filteredByName);
     }
 
-    private boolean isOverridden(AnnotatedMethod<?> superclassMethod, Set<AnnotatedMethod<?>> methods)
+    private boolean isOverridden(AnnotatedMethod<?> superclassMethod, Map<String, List<AnnotatedMethod<?>>> filteredByName)
     {
-        for (AnnotatedMethod<?> subclassMethod : methods)
+        // only methods with the same name can override, so restrict the scan to that bucket (avoids O(n^2))
+        List<AnnotatedMethod<?>> sameName = filteredByName.get(superclassMethod.getJavaMember().getName());
+        if (sameName == null)
+        {
+            return false;
+        }
+        for (AnnotatedMethod<?> subclassMethod : sameName)
         {
             if (ClassUtil.isOverridden(subclassMethod.getJavaMember(), superclassMethod.getJavaMember()))
             {