Skip to content

Commit e90fb0c

Browse files
Speedup SearchResponse serialization (elastic#123211)
No need to have a nested concat here. There's obviously lots and lots of room for optimization on this one, but just flattening out one obvious step here outright halves the number of method calls required when serializing a search response. Given that method calls can consume up to half the serialization cost this change might massively speed up some usecases.
1 parent 2988109 commit e90fb0c

File tree

1 file changed

+17
-9
lines changed

1 file changed

+17
-9
lines changed

server/src/main/java/org/elasticsearch/action/search/SearchResponse.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@
1414
import org.elasticsearch.action.OriginalIndices;
1515
import org.elasticsearch.common.Strings;
1616
import org.elasticsearch.common.bytes.BytesReference;
17+
import org.elasticsearch.common.collect.Iterators;
1718
import org.elasticsearch.common.io.stream.DelayableWriteable;
1819
import org.elasticsearch.common.io.stream.StreamInput;
1920
import org.elasticsearch.common.io.stream.StreamOutput;
2021
import org.elasticsearch.common.io.stream.Writeable;
2122
import org.elasticsearch.common.lucene.Lucene;
2223
import org.elasticsearch.common.util.concurrent.ConcurrentCollections;
23-
import org.elasticsearch.common.xcontent.ChunkedToXContent;
24+
import org.elasticsearch.common.xcontent.ChunkedToXContentHelper;
2425
import org.elasticsearch.common.xcontent.ChunkedToXContentObject;
2526
import org.elasticsearch.core.Nullable;
2627
import org.elasticsearch.core.RefCounted;
@@ -391,17 +392,24 @@ public Clusters getClusters() {
391392
@Override
392393
public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params params) {
393394
assert hasReferences();
394-
return ChunkedToXContent.builder(params).xContentObject(innerToXContentChunked(params));
395+
return getToXContentIterator(true, params);
395396
}
396397

397398
public Iterator<? extends ToXContent> innerToXContentChunked(ToXContent.Params params) {
398-
return ChunkedToXContent.builder(params)
399-
.append(SearchResponse.this::headerToXContent)
400-
.append(clusters)
401-
.append(hits)
402-
.appendIfPresent(aggregations)
403-
.appendIfPresent(suggest)
404-
.appendIfPresent(profileResults);
399+
return getToXContentIterator(false, params);
400+
}
401+
402+
private Iterator<ToXContent> getToXContentIterator(boolean wrapInObject, ToXContent.Params params) {
403+
return Iterators.concat(
404+
wrapInObject ? ChunkedToXContentHelper.startObject() : Collections.emptyIterator(),
405+
ChunkedToXContentHelper.singleChunk(SearchResponse.this::headerToXContent),
406+
Iterators.single(clusters),
407+
hits.toXContentChunked(params),
408+
aggregations == null ? Collections.emptyIterator() : ChunkedToXContentHelper.singleChunk(aggregations),
409+
suggest == null ? Collections.emptyIterator() : ChunkedToXContentHelper.singleChunk(suggest),
410+
profileResults == null ? Collections.emptyIterator() : ChunkedToXContentHelper.singleChunk(profileResults),
411+
wrapInObject ? ChunkedToXContentHelper.endObject() : Collections.emptyIterator()
412+
);
405413
}
406414

407415
public XContentBuilder headerToXContent(XContentBuilder builder, ToXContent.Params params) throws IOException {

0 commit comments

Comments
 (0)