Skip to content

Commit

Permalink
Speed up DocumentParser.innerParseObject (elastic#88715)
Browse files Browse the repository at this point in the history
Making this a little smaller so it inlines more often and more importantly
avoid getting the current field name redundantly before entering the loop which
is not free when the parser is a `DotExpandingXContentParser`.
This change gives a significant boost to `BeatsMapperBenchmark.benchmarkParseKeywordFields`.

Results below are pretty stable, running with a large number of iterations.

before:

```
Result "org.elasticsearch.benchmark.index.mapper.BeatsMapperBenchmark.benchmarkParseKeywordFields":
  9039.270 ±(99.9%) 28.001 ns/op [Average]
  (min, avg, max) = (9008.778, 9039.270, 9062.246), stdev = 18.521
  CI (99.9%): [9011.269, 9067.271] (assumes normal distribution)
```

after:

```
Result "org.elasticsearch.benchmark.index.mapper.BeatsMapperBenchmark.benchmarkParseKeywordFields":
  8645.649 ±(99.9%) 53.677 ns/op [Average]
  (min, avg, max) = (8568.319, 8645.649, 8688.210), stdev = 35.504
  CI (99.9%): [8591.972, 8699.327] (assumes normal distribution)
```
  • Loading branch information
original-brownbear authored Jul 22, 2022
1 parent e3dc098 commit b7e2d59
Showing 1 changed file with 8 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -294,17 +294,18 @@ private static void throwOnConcreteValue(ObjectMapper mapper, String currentFiel

private static void innerParseObject(DocumentParserContext context, ObjectMapper mapper) throws IOException {

XContentParser.Token token = context.parser().currentToken();
String currentFieldName = context.parser().currentName();
final XContentParser parser = context.parser();
XContentParser.Token token = parser.currentToken();
String currentFieldName = null;
assert token == XContentParser.Token.FIELD_NAME || token == XContentParser.Token.END_OBJECT;

while (token != XContentParser.Token.END_OBJECT) {
if (token == null) {
throwEOF(mapper, currentFieldName);
throwEOF(mapper, context);
}
switch (token) {
case FIELD_NAME:
currentFieldName = context.parser().currentName();
currentFieldName = parser.currentName();
if (currentFieldName.isBlank()) {
throwFieldNameBlank(context, currentFieldName);
}
Expand All @@ -324,7 +325,7 @@ private static void innerParseObject(DocumentParserContext context, ObjectMapper
}
break;
}
token = context.parser().nextToken();
token = parser.nextToken();
}
}

Expand All @@ -334,12 +335,12 @@ private static void throwFieldNameBlank(DocumentParserContext context, String cu
);
}

private static void throwEOF(ObjectMapper mapper, String currentFieldName) {
private static void throwEOF(ObjectMapper mapper, DocumentParserContext context) throws IOException {
throw new MapperParsingException(
"object mapping for ["
+ mapper.name()
+ "] tried to parse field ["
+ currentFieldName
+ context.parser().currentName()
+ "] as object, but got EOF, has a concrete value been provided to it?"
);
}
Expand Down

0 comments on commit b7e2d59

Please sign in to comment.