diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanDeployment.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanDeployment.java index 0a814bda4d4862..b1387f818a74fb 100644 --- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanDeployment.java +++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanDeployment.java @@ -68,6 +68,7 @@ public class BeanDeployment { private final Map stereotypes; private final List beans; + private volatile Map> beansByType = null; private final List interceptors; private final List decorators; @@ -231,6 +232,7 @@ BeanRegistrar.RegistrationContext registerBeans(List beanRegistra List injectionPoints = new ArrayList<>(); this.beans.addAll(findBeans(initBeanDefiningAnnotations(beanDefiningAnnotations, stereotypes.keySet()), observers, injectionPoints, jtaCapabilities)); + beansByType = null; // Note that we need to use view of the collections to reflect further additions, e.g. synthetic beans and observers buildContextPut(Key.BEANS.asString(), Collections.unmodifiableList(beans)); buildContextPut(Key.OBSERVERS.asString(), Collections.unmodifiableList(observers)); @@ -248,6 +250,7 @@ void init(Consumer bytecodeTransformerConsumer, List> additionalUnusedBeanExclusions) { long start = System.nanoTime(); + initBeanByTypeMap(); // Collect dependency resolution errors List errors = new ArrayList<>(); for (BeanInfo bean : beans) { @@ -279,11 +282,22 @@ void init(Consumer bytecodeTransformerConsumer, LOGGER.debugf("Removed %s beans, %s interceptors and %s decorators in %s ms", removedBeans.size(), removedInterceptors.size(), removedDecorators.size(), TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - removalStart)); + //we need to re-initialize it, so it does not contain removed beans + initBeanByTypeMap(); } buildContext.putInternal(BuildExtension.Key.REMOVED_BEANS.asString(), Collections.unmodifiableSet(removedBeans)); LOGGER.debugf("Bean deployment initialized in %s ms", TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start)); } + private void initBeanByTypeMap() { + beansByType = new HashMap<>(); + for (var bean : beans) { + for (var beanType : bean.types) { + beansByType.computeIfAbsent(beanType, (s) -> new ArrayList<>()).add(bean); + } + } + } + private void removeUnusedComponents(Set declaresObserver, List> allUnusedExclusions, Set removedDecorators, Set removedInterceptors) { @@ -375,6 +389,7 @@ private Set removeUnusedBeans(Set declaresObserver, List
 removableInjectionPoints = removableBeans.stream()
                     .flatMap(d -> d.getAllInjectionPoints().stream()).collect(Collectors.toList());
@@ -407,6 +422,14 @@ public Collection getBeans() {
         return Collections.unmodifiableList(beans);
     }
 
+    public Collection getBeansByType(Type type) {
+        var ret = beansByType.get(type);
+        if (ret == null) {
+            return Collections.emptyList();
+        }
+        return Collections.unmodifiableList(ret);
+    }
+
     public Collection getRemovedBeans() {
         return Collections.unmodifiableSet(removedBeans);
     }
@@ -1126,6 +1149,7 @@ private void addSyntheticBean(BeanInfo bean) {
             }
         }
         beans.add(bean);
+        beansByType = null;
     }
 
     private void addSyntheticObserver(ObserverConfigurator configurator) {
diff --git a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanResolverImpl.java b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanResolverImpl.java
index a085f58197861a..32297915115373 100644
--- a/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanResolverImpl.java
+++ b/independent-projects/arc/processor/src/main/java/io/quarkus/arc/processor/BeanResolverImpl.java
@@ -9,6 +9,7 @@
 
 import io.quarkus.arc.processor.InjectionPointInfo.TypeAndQualifiers;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
@@ -81,7 +82,11 @@ List resolve(TypeAndQualifiers typeAndQualifiers) {
 
     private List findMatching(TypeAndQualifiers typeAndQualifiers) {
         List resolved = new ArrayList<>();
-        for (BeanInfo b : beanDeployment.getBeans()) {
+        //optimisation for the simple class case
+        Collection potentialBeans = typeAndQualifiers.type.kind() == CLASS
+                ? beanDeployment.getBeansByType(typeAndQualifiers.type)
+                : beanDeployment.getBeans();
+        for (BeanInfo b : potentialBeans) {
             if (Beans.matches(b, typeAndQualifiers)) {
                 resolved.add(b);
             }
@@ -91,7 +96,10 @@ private List findMatching(TypeAndQualifiers typeAndQualifiers) {
 
     List findTypeMatching(Type type) {
         List resolved = new ArrayList<>();
-        for (BeanInfo b : beanDeployment.getBeans()) {
+        //optimisation for the simple class case
+        Collection potentialBeans = type.kind() == CLASS ? beanDeployment.getBeansByType(type)
+                : beanDeployment.getBeans();
+        for (BeanInfo b : potentialBeans) {
             if (Beans.matchesType(b, type)) {
                 resolved.add(b);
             }