Avoid java.util.stream.Stream usage in hot paths
Prior to this commit, profiling sessions would show that using `java.util.stream.Stream` in some hot code paths creates significant garbage. Where streams aren't really required, this commit turns those snippets into imperative logic because those are likely to be called once or multiple times per request. Closes gh-22341
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -141,15 +141,17 @@ public class ReactiveAdapterRegistry {
|
||||
if (clazz == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return this.adapters.stream()
|
||||
.filter(adapter -> adapter.getReactiveType() == clazz)
|
||||
.findFirst()
|
||||
.orElseGet(() ->
|
||||
this.adapters.stream()
|
||||
.filter(adapter -> adapter.getReactiveType().isAssignableFrom(clazz))
|
||||
.findFirst()
|
||||
.orElse(null));
|
||||
for(ReactiveAdapter adapter : this.adapters) {
|
||||
if (adapter.getReactiveType() == clazz) {
|
||||
return adapter;
|
||||
}
|
||||
}
|
||||
for(ReactiveAdapter adapter : this.adapters) {
|
||||
if (adapter.getReactiveType().isAssignableFrom(clazz)) {
|
||||
return adapter;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -74,7 +74,12 @@ public abstract class AbstractEncoder<T> implements Encoder<T> {
|
||||
if (mimeType == null) {
|
||||
return true;
|
||||
}
|
||||
return this.encodableMimeTypes.stream().anyMatch(candidate -> candidate.isCompatibleWith(mimeType));
|
||||
for(MimeType candidate : this.encodableMimeTypes) {
|
||||
if (candidate.isCompatibleWith(mimeType)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -63,7 +63,12 @@ final class CompositeLog implements Log {
|
||||
}
|
||||
|
||||
private static Log initLogger(List<Log> loggers, Predicate<Log> predicate) {
|
||||
return loggers.stream().filter(predicate).findFirst().orElse(NO_OP_LOG);
|
||||
for (Log logger : loggers) {
|
||||
if (predicate.test(logger)) {
|
||||
return logger;
|
||||
}
|
||||
}
|
||||
return NO_OP_LOG;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package org.springframework.web.reactive.result.method.annotation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.core.publisher.Mono;
|
||||
@@ -137,7 +137,8 @@ public abstract class AbstractMessageWriterResultHandler extends HandlerResultHa
|
||||
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
ServerHttpResponse response = exchange.getResponse();
|
||||
MediaType bestMediaType = selectMediaType(exchange, () -> getMediaTypesFor(elementType));
|
||||
List<MediaType> writableMediaTypes = getMediaTypesFor(elementType);
|
||||
MediaType bestMediaType = selectMediaType(exchange, () -> writableMediaTypes);
|
||||
if (bestMediaType != null) {
|
||||
String logPrefix = exchange.getLogPrefix();
|
||||
if (logger.isDebugEnabled()) {
|
||||
@@ -152,12 +153,12 @@ public abstract class AbstractMessageWriterResultHandler extends HandlerResultHa
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (getMediaTypesFor(elementType).isEmpty()) {
|
||||
if (writableMediaTypes.isEmpty()) {
|
||||
return Mono.error(new IllegalStateException("No writer for : " + elementType));
|
||||
}
|
||||
}
|
||||
|
||||
return Mono.error(new NotAcceptableStatusException(getMediaTypesFor(elementType)));
|
||||
return Mono.error(new NotAcceptableStatusException(writableMediaTypes));
|
||||
}
|
||||
|
||||
private ResolvableType getElementType(ReactiveAdapter adapter, ResolvableType genericType) {
|
||||
@@ -173,10 +174,13 @@ public abstract class AbstractMessageWriterResultHandler extends HandlerResultHa
|
||||
}
|
||||
|
||||
private List<MediaType> getMediaTypesFor(ResolvableType elementType) {
|
||||
return getMessageWriters().stream()
|
||||
.filter(converter -> converter.canWrite(elementType, null))
|
||||
.flatMap(converter -> converter.getWritableMediaTypes().stream())
|
||||
.collect(Collectors.toList());
|
||||
List<MediaType> writableMediaTypes = new ArrayList<>();
|
||||
for (HttpMessageWriter<?> converter : getMessageWriters()) {
|
||||
if (converter.canWrite(elementType, null)) {
|
||||
writableMediaTypes.addAll(converter.getWritableMediaTypes());
|
||||
}
|
||||
}
|
||||
return writableMediaTypes;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user