Optimize some iterations in BodyExtractor and BodyInserter
This commit turns some stream-based iterations back into simpler enhanced for loops. For simple use cases like these, where the stream API is merely used to map/filter + collect to a List, a for loop is more efficient. This is especially true for small collections like the ones we deal with in BodyInserters/BodyExtractors here (in the order of 50ns/op vs 5ns/op). These cases are also simple enough that they don't lose in readability after the conversion. Closes gh-30136
This commit is contained in:
parent
4e896c8125
commit
800b13492b
|
@ -147,8 +147,10 @@ public abstract class AbstractClientHttpRequest implements ClientHttpRequest {
|
|||
this.commitActions.add(writeAction);
|
||||
}
|
||||
|
||||
List<? extends Publisher<Void>> actions = this.commitActions.stream()
|
||||
.map(Supplier::get).toList();
|
||||
List<Publisher<Void>> actions = new ArrayList<>(this.commitActions.size());
|
||||
for (Supplier<? extends Publisher<Void>> commitAction : this.commitActions) {
|
||||
actions.add(commitAction.get());
|
||||
}
|
||||
|
||||
return Flux.concat(actions).then();
|
||||
}
|
||||
|
|
|
@ -194,18 +194,16 @@ public abstract class BodyExtractors {
|
|||
MediaType contentType = Optional.ofNullable(message.getHeaders().getContentType())
|
||||
.orElse(MediaType.APPLICATION_OCTET_STREAM);
|
||||
|
||||
return context.messageReaders().stream()
|
||||
.filter(reader -> reader.canRead(elementType, contentType))
|
||||
.findFirst()
|
||||
.map(BodyExtractors::<T>cast)
|
||||
.map(readerFunction)
|
||||
.orElseGet(() -> {
|
||||
List<MediaType> mediaTypes = context.messageReaders().stream()
|
||||
.flatMap(reader -> reader.getReadableMediaTypes(elementType).stream())
|
||||
.toList();
|
||||
return errorFunction.apply(
|
||||
new UnsupportedMediaTypeException(contentType, mediaTypes, elementType));
|
||||
});
|
||||
for (HttpMessageReader<?> messageReader : context.messageReaders()) {
|
||||
if (messageReader.canRead(elementType, contentType)) {
|
||||
return readerFunction.apply(cast(messageReader));
|
||||
}
|
||||
}
|
||||
List<MediaType> mediaTypes = context.messageReaders().stream()
|
||||
.flatMap(reader -> reader.getReadableMediaTypes(elementType).stream())
|
||||
.toList();
|
||||
return errorFunction.apply(
|
||||
new UnsupportedMediaTypeException(contentType, mediaTypes, elementType));
|
||||
}
|
||||
|
||||
private static <T> Mono<T> readToMono(ReactiveHttpInputMessage message, BodyExtractor.Context context,
|
||||
|
@ -245,12 +243,13 @@ public abstract class BodyExtractors {
|
|||
private static <T> HttpMessageReader<T> findReader(
|
||||
ResolvableType elementType, MediaType mediaType, BodyExtractor.Context context) {
|
||||
|
||||
return context.messageReaders().stream()
|
||||
.filter(messageReader -> messageReader.canRead(elementType, mediaType))
|
||||
.findFirst()
|
||||
.map(BodyExtractors::<T>cast)
|
||||
.orElseThrow(() -> new IllegalStateException(
|
||||
"No HttpMessageReader for \"" + mediaType + "\" and \"" + elementType + "\""));
|
||||
for (HttpMessageReader<?> messageReader : context.messageReaders()) {
|
||||
if (messageReader.canRead(elementType, mediaType)) {
|
||||
return cast(messageReader);
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"No HttpMessageReader for \"" + mediaType + "\" and \"" + elementType + "\"");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
|
@ -373,12 +373,13 @@ public abstract class BodyInserters {
|
|||
publisher = Mono.just(body);
|
||||
}
|
||||
MediaType mediaType = outputMessage.getHeaders().getContentType();
|
||||
return context.messageWriters().stream()
|
||||
.filter(messageWriter -> messageWriter.canWrite(bodyType, mediaType))
|
||||
.findFirst()
|
||||
.map(BodyInserters::cast)
|
||||
.map(writer -> write(publisher, bodyType, mediaType, outputMessage, context, writer))
|
||||
.orElseGet(() -> Mono.error(unsupportedError(bodyType, context, mediaType)));
|
||||
for (HttpMessageWriter<?> messageWriter : context.messageWriters()) {
|
||||
if (messageWriter.canWrite(bodyType, mediaType)) {
|
||||
HttpMessageWriter<Object> typedMessageWriter = cast(messageWriter);
|
||||
return write(publisher, bodyType, mediaType, outputMessage, context, typedMessageWriter);
|
||||
}
|
||||
}
|
||||
return Mono.error(unsupportedError(bodyType, context, mediaType));
|
||||
}
|
||||
|
||||
private static UnsupportedMediaTypeException unsupportedError(ResolvableType bodyType,
|
||||
|
@ -406,12 +407,13 @@ public abstract class BodyInserters {
|
|||
private static <T> HttpMessageWriter<T> findWriter(
|
||||
BodyInserter.Context context, ResolvableType elementType, @Nullable MediaType mediaType) {
|
||||
|
||||
return context.messageWriters().stream()
|
||||
.filter(messageWriter -> messageWriter.canWrite(elementType, mediaType))
|
||||
.findFirst()
|
||||
.map(BodyInserters::<T>cast)
|
||||
.orElseThrow(() -> new IllegalStateException(
|
||||
"No HttpMessageWriter for \"" + mediaType + "\" and \"" + elementType + "\""));
|
||||
for (HttpMessageWriter<?> messageWriter : context.messageWriters()) {
|
||||
if (messageWriter.canWrite(elementType, mediaType)) {
|
||||
return cast(messageWriter);
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"No HttpMessageWriter for \"" + mediaType + "\" and \"" + elementType + "\"");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
Loading…
Reference in New Issue