Skip to content

Commit

Permalink
Avoid resizing of fixed-size HashSet/LinkedHashSet variants
Browse files Browse the repository at this point in the history
Add helpers to CollectionUtils for building HashSets and LinkedHashSets
that can hold an expected number of elements without needing to resize / rehash.
  • Loading branch information
kilink committed Feb 19, 2024
1 parent c6e6a3e commit 8a90e3a
Show file tree
Hide file tree
Showing 47 changed files with 114 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
Expand Down Expand Up @@ -164,7 +165,7 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA

protected final Log logger = LogFactory.getLog(getClass());

private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = CollectionUtils.newLinkedHashSet(4);

private String requiredParameterName = "required";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ public LifecycleMetadata(Class<?> beanClass, Collection<LifecycleMethod> initMet
}

public void checkInitDestroyMethods(RootBeanDefinition beanDefinition) {
Set<LifecycleMethod> checkedInitMethods = new LinkedHashSet<>(this.initMethods.size());
Set<LifecycleMethod> checkedInitMethods = CollectionUtils.newLinkedHashSet(this.initMethods.size());
for (LifecycleMethod lifecycleMethod : this.initMethods) {
String methodIdentifier = lifecycleMethod.getIdentifier();
if (!beanDefinition.isExternallyManagedInitMethod(methodIdentifier)) {
Expand All @@ -374,7 +374,7 @@ public void checkInitDestroyMethods(RootBeanDefinition beanDefinition) {
}
}
}
Set<LifecycleMethod> checkedDestroyMethods = new LinkedHashSet<>(this.destroyMethods.size());
Set<LifecycleMethod> checkedDestroyMethods = CollectionUtils.newLinkedHashSet(this.destroyMethods.size());
for (LifecycleMethod lifecycleMethod : this.destroyMethods) {
String methodIdentifier = lifecycleMethod.getIdentifier();
if (!beanDefinition.isExternallyManagedDestroyMethod(methodIdentifier)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;

import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;

/**
Expand Down Expand Up @@ -124,7 +124,7 @@ public void checkConfigMembers(RootBeanDefinition beanDefinition) {
this.checkedElements = Collections.emptySet();
}
else {
Set<InjectedElement> checkedElements = new LinkedHashSet<>((this.injectedElements.size() * 4 / 3) + 1);
Set<InjectedElement> checkedElements = CollectionUtils.newLinkedHashSet(this.injectedElements.size());
for (InjectedElement element : this.injectedElements) {
Member member = element.getMember();
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Method;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;

Expand All @@ -40,6 +39,7 @@
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

/**
Expand All @@ -59,7 +59,7 @@
*/
public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwareAutowireCandidateResolver {

private final Set<Class<? extends Annotation>> qualifierTypes = new LinkedHashSet<>(2);
private final Set<Class<? extends Annotation>> qualifierTypes = CollectionUtils.newLinkedHashSet(2);

private Class<? extends Annotation> valueAnnotationType = Value.class;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.stream.Collectors;

Expand All @@ -34,6 +33,7 @@
import org.springframework.core.MethodParameter;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.function.ThrowingConsumer;

Expand Down Expand Up @@ -165,7 +165,7 @@ private AutowiredArguments resolveArguments(RegisteredBean registeredBean,
AutowireCapableBeanFactory autowireCapableBeanFactory = (AutowireCapableBeanFactory) beanFactory;
int argumentCount = method.getParameterCount();
Object[] arguments = new Object[argumentCount];
Set<String> autowiredBeanNames = new LinkedHashSet<>(argumentCount);
Set<String> autowiredBeanNames = CollectionUtils.newLinkedHashSet(argumentCount);
TypeConverter typeConverter = beanFactory.getTypeConverter();
for (int i = 0; i < argumentCount; i++) {
MethodParameter parameter = new MethodParameter(method, i);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
Expand All @@ -49,6 +48,7 @@
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.function.ThrowingBiFunction;
Expand Down Expand Up @@ -289,7 +289,7 @@ private ValueHolder[] resolveArgumentValues(RegisteredBean registeredBean, Execu
beanFactory, registeredBean.getBeanName(), beanDefinition, beanFactory.getTypeConverter());
ConstructorArgumentValues values = resolveConstructorArguments(
valueResolver, beanDefinition.getConstructorArgumentValues());
Set<ValueHolder> usedValueHolders = new HashSet<>(parameters.length);
Set<ValueHolder> usedValueHolders = CollectionUtils.newHashSet(parameters.length);
for (int i = 0; i < parameters.length; i++) {
Class<?> parameterType = parameters[i].getType();
String parameterName = (parameters[i].isNamePresent() ? parameters[i].getName() : null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@

package org.springframework.beans.factory.config;

import java.util.LinkedHashSet;
import java.util.Set;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.TypeConverter;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;

/**
* Simple factory for shared Set instances. Allows for central setup
Expand Down Expand Up @@ -85,7 +85,7 @@ protected Set<Object> createInstance() {
result = BeanUtils.instantiateClass(this.targetSetClass);
}
else {
result = new LinkedHashSet<>(this.sourceSet.size());
result = CollectionUtils.newLinkedHashSet(this.sourceSet.size());
}
Class<?> valueType = null;
if (this.targetSetClass != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.ReflectionUtils.MethodCallback;
Expand Down Expand Up @@ -616,7 +617,7 @@ protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
Set<String> actualDependentBeans = CollectionUtils.newLinkedHashSet(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
Expand Down Expand Up @@ -765,7 +766,7 @@ protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition m
paramNames = pnd.getParameterNames(candidate);
}
}
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = CollectionUtils.newHashSet(paramTypes.length);
Object[] args = new Object[paramTypes.length];
for (int i = 0; i < args.length; i++) {
ConstructorArgumentValues.ValueHolder valueHolder = cav.getArgumentValue(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
Expand Down Expand Up @@ -74,6 +73,7 @@
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.StringValueResolver;
Expand Down Expand Up @@ -1153,7 +1153,7 @@ protected void beforePrototypeCreation(String beanName) {
this.prototypesCurrentlyInCreation.set(beanName);
}
else if (curVal instanceof String strValue) {
Set<String> beanNameSet = new HashSet<>(2);
Set<String> beanNameSet = CollectionUtils.newHashSet(2);
beanNameSet.add(strValue);
beanNameSet.add(beanName);
this.prototypesCurrentlyInCreation.set(beanNameSet);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ private List<?> resolveManagedList(Object argName, List<?> ml) {
* For each element in the managed set, resolve reference if necessary.
*/
private Set<?> resolveManagedSet(Object argName, Set<?> ms) {
Set<Object> resolved = new LinkedHashSet<>(ms.size());
Set<Object> resolved = CollectionUtils.newLinkedHashSet(ms.size());
int i = 0;
for (Object m : ms) {
resolved.add(resolveValueIfNecessary(new KeyedArgName(argName, i), m));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MethodInvoker;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
Expand Down Expand Up @@ -598,7 +599,7 @@ else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
}
}
else if (resolvedValues != null) {
Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
Set<ValueHolder> valueHolders = CollectionUtils.newLinkedHashSet(resolvedValues.getArgumentCount());
valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
valueHolders.addAll(resolvedValues.getGenericArgumentValues());
for (ValueHolder value : valueHolders) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.Set;

import org.springframework.core.io.Resource;
import org.springframework.util.CollectionUtils;

/**
* @author Juergen Hoeller
Expand Down Expand Up @@ -266,7 +267,7 @@ public Set<CustomEnum> getCustomEnumSetMismatch() {
}

public void setCustomEnumSetMismatch(Set<String> customEnumSet) {
this.customEnumSet = new HashSet<>(customEnumSet.size());
this.customEnumSet = CollectionUtils.newHashSet(customEnumSet.size());
for (String customEnumName : customEnumSet) {
this.customEnumSet.add(CustomEnum.valueOf(customEnumName));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
package org.springframework.cache.interceptor;

import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;

import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

/**
* Base class for cache operations.
Expand Down Expand Up @@ -158,7 +158,7 @@ public void setCacheName(String cacheName) {
}

public void setCacheNames(String... cacheNames) {
this.cacheNames = new LinkedHashSet<>(cacheNames.length);
this.cacheNames = CollectionUtils.newLinkedHashSet(cacheNames.length);
for (String cacheName : cacheNames) {
Assert.hasText(cacheName, "Cache name must be non-empty if specified");
this.cacheNames.add(cacheName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.lang.Nullable;
import org.springframework.util.CollectionUtils;

/**
* Abstract base class implementing the common {@link CacheManager} methods.
Expand Down Expand Up @@ -64,7 +65,7 @@ public void initializeCaches() {
synchronized (this.cacheMap) {
this.cacheNames = Collections.emptySet();
this.cacheMap.clear();
Set<String> cacheNames = new LinkedHashSet<>(caches.size());
Set<String> cacheNames = CollectionUtils.newLinkedHashSet(caches.size());
for (Cache cache : caches) {
String name = cache.getName();
this.cacheMap.put(name, decorateCache(cache));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package org.springframework.context.annotation;

import java.lang.annotation.Annotation;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.function.Predicate;

Expand All @@ -38,6 +37,7 @@
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;

/**
* Utility class that allows for convenient registration of common
Expand Down Expand Up @@ -154,7 +154,7 @@ public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
}
}

Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
Set<BeanDefinitionHolder> beanDefs = CollectionUtils.newLinkedHashSet(6);

if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
Expand Down Expand Up @@ -148,7 +149,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
private static final boolean jndiPresent = ClassUtils.isPresent(
"javax.naming.InitialContext", CommonAnnotationBeanPostProcessor.class.getClassLoader());

private static final Set<Class<? extends Annotation>> resourceAnnotationTypes = new LinkedHashSet<>(4);
private static final Set<Class<? extends Annotation>> resourceAnnotationTypes = CollectionUtils.newLinkedHashSet(3);

@Nullable
private static final Class<? extends Annotation> jakartaResourceType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ private Set<MethodMetadata> retrieveBeanMethodMetadata(SourceClass sourceClass)
Set<MethodMetadata> asmMethods = asm.getAnnotatedMethods(Bean.class.getName());
if (asmMethods.size() >= beanMethods.size()) {
Set<MethodMetadata> candidateMethods = new LinkedHashSet<>(beanMethods);
Set<MethodMetadata> selectedMethods = new LinkedHashSet<>(asmMethods.size());
Set<MethodMetadata> selectedMethods = CollectionUtils.newLinkedHashSet(asmMethods.size());
for (MethodMetadata asmMethod : asmMethods) {
for (Iterator<MethodMetadata> it = candidateMethods.iterator(); it.hasNext();) {
MethodMetadata beanMethod = it.next();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.
this.resourceLoader, this.componentScanBeanNameGenerator, registry);

Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
Set<ConfigurationClass> alreadyParsed = CollectionUtils.newHashSet(configCandidates.size());
do {
StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
parser.parse(candidates);
Expand All @@ -433,7 +433,7 @@ else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = Set.of(candidateNames);
Set<String> alreadyParsedClasses = new HashSet<>();
Set<String> alreadyParsedClasses = CollectionUtils.newHashSet(alreadyParsed.size());
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -883,7 +882,7 @@ private ModelMBeanInfo getMBeanInfo(Object managedBean, String beanKey) throws J
*/
private void autodetect(Map<String, Object> beans, AutodetectCallback callback) {
Assert.state(this.beanFactory != null, "No BeanFactory set");
Set<String> beanNames = new LinkedHashSet<>(this.beanFactory.getBeanDefinitionCount());
Set<String> beanNames = CollectionUtils.newLinkedHashSet(this.beanFactory.getBeanDefinitionCount());
Collections.addAll(beanNames, this.beanFactory.getBeanDefinitionNames());
if (this.beanFactory instanceof ConfigurableBeanFactory cbf) {
Collections.addAll(beanNames, cbf.getSingletonNames());
Expand Down
Loading

0 comments on commit 8a90e3a

Please sign in to comment.