Skip to content

Commit 5d62827

Browse files
authored
Optimize ArrayList allocations (#3233)
* Optimize `ArrayList` allocations Fix `new ArrayList()` calls with explicit size or collection copy whenever it is possible or reasonable * Fix typo in the `MessageListenerAdapter` Javadoc
1 parent 6fba942 commit 5d62827

File tree

15 files changed

+67
-46
lines changed

15 files changed

+67
-46
lines changed

spring-amqp/src/main/java/org/springframework/amqp/core/AbstractDeclarable.java

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
* @author Gary Russell
3636
* @author Christian Tzolov
3737
* @author Ngoc Nhan
38+
* @author Artem Bilan
39+
*
3840
* @since 1.2
3941
*
4042
*/
@@ -104,16 +106,20 @@ public void setIgnoreDeclarationExceptions(boolean ignoreDeclarationExceptions)
104106
@Override
105107
@SuppressWarnings("NullAway") // Dataflow analysis limitation
106108
public void setAdminsThatShouldDeclare(@Nullable Object @Nullable ... adminArgs) {
107-
Collection<Object> admins = new ArrayList<>();
108109
if (adminArgs != null) {
109110
if (adminArgs.length > 1) {
110111
Assert.noNullElements(adminArgs, "'admins' cannot contain null elements");
111112
}
112113
if (adminArgs.length > 0 && !(adminArgs.length == 1 && adminArgs[0] == null)) {
113-
admins = Arrays.asList(adminArgs);
114+
this.declaringAdmins = Arrays.asList(adminArgs);
115+
}
116+
else {
117+
this.declaringAdmins = Collections.emptyList();
114118
}
115119
}
116-
this.declaringAdmins = admins;
120+
else {
121+
this.declaringAdmins = Collections.emptyList();
122+
}
117123
}
118124

119125
@Override

spring-amqp/src/main/java/org/springframework/amqp/core/Declarables.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,20 +31,27 @@
3131
*
3232
* @author Gary Russell
3333
* @author Björn Michael
34+
* @author Artem Bilan
35+
*
3436
* @since 2.1
3537
*/
3638
public class Declarables {
3739

38-
private final Collection<Declarable> declarables = new ArrayList<>();
40+
private final Collection<Declarable> declarables;
3941

4042
public Declarables(Declarable... declarables) {
4143
if (!ObjectUtils.isEmpty(declarables)) {
44+
this.declarables = new ArrayList<>(declarables.length);
4245
this.declarables.addAll(Arrays.asList(declarables));
4346
}
47+
else {
48+
this.declarables = new ArrayList<>();
49+
}
4450
}
4551

4652
public Declarables(Collection<? extends Declarable> declarables) {
4753
Assert.notNull(declarables, "declarables cannot be null");
54+
this.declarables = new ArrayList<>(declarables.size());
4855
this.declarables.addAll(declarables);
4956
}
5057

spring-amqp/src/main/java/org/springframework/amqp/support/postprocessor/MessagePostProcessorUtils.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,10 @@
3838
public final class MessagePostProcessorUtils {
3939

4040
public static Collection<MessagePostProcessor> sort(Collection<MessagePostProcessor> processors) {
41-
List<MessagePostProcessor> priorityOrdered = new ArrayList<>();
42-
List<MessagePostProcessor> ordered = new ArrayList<>();
43-
List<MessagePostProcessor> unOrdered = new ArrayList<>();
41+
int potentialSize = processors.size();
42+
List<MessagePostProcessor> priorityOrdered = new ArrayList<>(potentialSize);
43+
List<MessagePostProcessor> ordered = new ArrayList<>(potentialSize);
44+
List<MessagePostProcessor> unOrdered = new ArrayList<>(potentialSize);
4445
for (MessagePostProcessor processor : processors) {
4546
if (processor instanceof PriorityOrdered) {
4647
priorityOrdered.add(processor);

spring-rabbit-stream/src/main/java/org/springframework/rabbit/stream/config/SuperStream.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,9 @@ private static Collection<Declarable> declarables(String name, int partitions,
102102
BiFunction<String, Integer, List<String>> routingKeyStrategy,
103103
Map<String, Object> arguments) {
104104

105-
List<Declarable> declarables = new ArrayList<>();
106105
List<String> rks = routingKeyStrategy.apply(name, partitions);
107106
Assert.state(rks.size() == partitions, () -> "Expected " + partitions + " routing keys, not " + rks.size());
107+
List<Declarable> declarables = new ArrayList<>(partitions + 1);
108108
declarables.add(
109109
new DirectExchange(name, true, false, Map.<String, @Nullable Object>of("x-super-stream", true)));
110110

spring-rabbit/src/main/java/org/springframework/amqp/rabbit/annotation/RabbitListenerAnnotationBeanPostProcessor.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ else if (source instanceof Method method) {
361361
private void processMultiMethodListeners(RabbitListener[] classLevelListeners, Method[] multiMethods,
362362
Object bean, String beanName) {
363363

364-
List<Method> checkedMethods = new ArrayList<>();
364+
List<Method> checkedMethods = new ArrayList<>(multiMethods.length);
365365
Method defaultMethod = null;
366366
for (Method method : multiMethods) {
367367
Method checked = checkProxy(method, bean);
@@ -646,8 +646,8 @@ private List<Object> resolveQueues(RabbitListener rabbitListener, Collection<Dec
646646
String[] queues = rabbitListener.queues();
647647
QueueBinding[] bindings = rabbitListener.bindings();
648648
org.springframework.amqp.rabbit.annotation.Queue[] queuesToDeclare = rabbitListener.queuesToDeclare();
649-
List<String> queueNames = new ArrayList<>();
650-
List<Queue> queueBeans = new ArrayList<>();
649+
List<String> queueNames = new ArrayList<>(queues.length);
650+
List<Queue> queueBeans = new ArrayList<>(queues.length);
651651
for (String queue : queues) {
652652
resolveQueues(queue, queueNames, queueBeans);
653653
}
@@ -818,7 +818,7 @@ private void registerBindings(QueueBinding binding, String queueName, String exc
818818
}
819819
else {
820820
final int length = binding.key().length;
821-
routingKeys = new ArrayList<>();
821+
routingKeys = new ArrayList<>(length);
822822
for (int i = 0; i < length; ++i) {
823823
resolveAsStringOrQueue(resolveExpression(binding.key()[i]), routingKeys, null, "@QueueBinding.key");
824824
}

spring-rabbit/src/main/java/org/springframework/amqp/rabbit/batch/SimpleBatchingStrategy.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@
3737
/**
3838
* A simple batching strategy that supports only one exchange/routingKey; includes a batch
3939
* size, a batched message size limit and a timeout. The message properties from the first
40-
* message in the batch is used in the batch message. Each message is preceded by a 4 byte
40+
* message in the batch are used in the batch message. Each message is preceded by a 4-byte
4141
* length field.
4242
*
4343
* @author Gary Russell
4444
* @author Ngoc Nhan
45+
* @author Artem Bilan
46+
*
4547
* @since 1.4.1
4648
*
4749
*/
@@ -53,7 +55,7 @@ public class SimpleBatchingStrategy implements BatchingStrategy {
5355

5456
private final long timeout;
5557

56-
private final List<Message> messages = new ArrayList<>();
58+
private final List<Message> messages;
5759

5860
private @Nullable String exchange;
5961

@@ -68,6 +70,7 @@ public class SimpleBatchingStrategy implements BatchingStrategy {
6870
* @param timeout the batch timeout.
6971
*/
7072
public SimpleBatchingStrategy(int batchSize, int bufferLimit, long timeout) {
73+
this.messages = new ArrayList<>(batchSize);
7174
this.batchSize = batchSize;
7275
this.bufferLimit = bufferLimit;
7376
this.timeout = timeout;

spring-rabbit/src/main/java/org/springframework/amqp/rabbit/config/CompositeContainerCustomizer.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,21 @@
3030
*
3131
* @author Rene Felgentraeger
3232
* @author Gary Russell
33+
* @author Artem Bilan
3334
*
3435
* @since 2.4.8
3536
*/
3637
public class CompositeContainerCustomizer<C extends MessageListenerContainer> implements ContainerCustomizer<C> {
3738

38-
private final List<ContainerCustomizer<C>> customizers = new ArrayList<>();
39+
private final List<ContainerCustomizer<C>> customizers;
3940

4041
/**
4142
* Create an instance with the provided delegate customizers.
4243
* @param customizers the customizers.
4344
*/
4445
public CompositeContainerCustomizer(List<ContainerCustomizer<C>> customizers) {
4546
Assert.notNull(customizers, "At least one customizer must be present");
46-
this.customizers.addAll(customizers);
47+
this.customizers = new ArrayList<>(customizers);
4748
}
4849

4950
@Override

spring-rabbit/src/main/java/org/springframework/amqp/rabbit/connection/PublisherCallbackChannelImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -917,7 +917,7 @@ public Collection<PendingConfirm> expire(Listener listener, long cutoffTime) {
917917
return Collections.emptyList();
918918
}
919919

920-
List<PendingConfirm> expired = new ArrayList<>();
920+
List<PendingConfirm> expired = new ArrayList<>(pendingConfirmsForListener.size());
921921
Iterator<Entry<Long, PendingConfirm>> iterator = pendingConfirmsForListener.entrySet().iterator();
922922
while (iterator.hasNext()) {
923923
PendingConfirm pendingConfirm = iterator.next().getValue();
@@ -926,7 +926,7 @@ public Collection<PendingConfirm> expire(Listener listener, long cutoffTime) {
926926
iterator.remove();
927927
CorrelationData correlationData = pendingConfirm.getCorrelationData();
928928
if (correlationData != null && StringUtils.hasText(correlationData.getId())) {
929-
this.pendingReturns.remove(correlationData.getId()); // NOSONAR never null
929+
this.pendingReturns.remove(correlationData.getId());
930930
}
931931
}
932932
else {

spring-rabbit/src/main/java/org/springframework/amqp/rabbit/core/RabbitTemplate.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ public void setBeforePublishPostProcessors(MessagePostProcessor... beforePublish
679679
public void addBeforePublishPostProcessors(MessagePostProcessor... beforePublishPostProcessors) {
680680
Assert.notNull(beforePublishPostProcessors, "'beforePublishPostProcessors' cannot be null");
681681
if (this.beforePublishPostProcessors == null) {
682-
this.beforePublishPostProcessors = new ArrayList<>();
682+
this.beforePublishPostProcessors = new ArrayList<>(beforePublishPostProcessors.length);
683683
}
684684
this.beforePublishPostProcessors.addAll(Arrays.asList(beforePublishPostProcessors));
685685
this.beforePublishPostProcessors = MessagePostProcessorUtils.sort(this.beforePublishPostProcessors);
@@ -740,7 +740,7 @@ public void setAfterReceivePostProcessors(MessagePostProcessor... afterReceivePo
740740
public void addAfterReceivePostProcessors(MessagePostProcessor... afterReceivePostProcessors) {
741741
Assert.notNull(afterReceivePostProcessors, "'afterReceivePostProcessors' cannot be null");
742742
if (this.afterReceivePostProcessors == null) {
743-
this.afterReceivePostProcessors = new ArrayList<>();
743+
this.afterReceivePostProcessors = new ArrayList<>(afterReceivePostProcessors.length);
744744
}
745745
this.afterReceivePostProcessors.addAll(Arrays.asList(afterReceivePostProcessors));
746746
this.afterReceivePostProcessors = MessagePostProcessorUtils.sort(this.afterReceivePostProcessors);

spring-rabbit/src/main/java/org/springframework/amqp/rabbit/listener/MultiMethodRabbitListenerEndpoint.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public void setValidator(Validator validator) {
7171

7272
@Override
7373
protected HandlerAdapter configureListenerAdapter(MessagingMessageListenerAdapter messageListener) {
74-
List<InvocableHandlerMethod> invocableHandlerMethods = new ArrayList<>();
74+
List<InvocableHandlerMethod> invocableHandlerMethods = new ArrayList<>(this.methods.size());
7575
InvocableHandlerMethod defaultHandler = null;
7676
MessageHandlerMethodFactory messageHandlerMethodFactory = getMessageHandlerMethodFactory();
7777
Assert.state(messageHandlerMethodFactory != null,

0 commit comments

Comments
 (0)