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()))
{