-
Notifications
You must be signed in to change notification settings - Fork 25.2k
Improve exception handling for JsonXContentParser #123439
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like this could possibly have an impact on json parsing speed due to introducing lambdas at every token event. Is the lambda needed?
cc @original-brownbear
@rjernst Thanks, I did not consider the performance aspect, I'll look into that. The lambda is strictly speaking not necessary, that part was added to avoid copypasting try/catch all over, but if it kills the performance then I can go back to copypasting. |
Yea we can't do this, this is going to annihilate performance I would expect. We have some jmh benchmarks around mapper parsing that will probably show this quite clearly. |
I run |
@smalyshev Does that benchmark even exercise this code path much? Almost looks like it just delegates to I'd expect |
@original-brownbear OK I'll try |
@original-brownbear So this is what I get on the Google VM:
with the patch
I'm not sure why the patch gets a tiny bit faster results, but it seems to be all within the error bars. Any other suggestions about how I could test it? |
459d209
to
d37e09c
Compare
Pinging @elastic/es-core-infra (Team:Core/Infra) |
@smalyshev even if you cannot show a regression in a microbenchmark. I would strongly discourage this kind of change. It might be that the compiler is able to inline the whole thing. But also it could be that for some percentage of runs It won't be able to do so (JIT is not deterministic at all and you might even be able to reproduce this fact by rerunning the benchmark a couple times in fresh JVMs). I also gave that benchmark a spin and it's not a good reproducer sadly because it mostly goes through the dot expanding parser which has so much overhead that it drowns out the overhead here. Sorry for the inaccurate suggestion, I couldn't find a good Rally run at all when I just checked. |
Maybe we could add parser-specific microbenchmark if the existing ones aren't good enough? It's not hard for me to unroll the lambdas, but if we don't have the good benchmark I can't be sure any change wouldn't be problematic so there's something that needs to be improved regardless. |
f71d3c9
to
900da19
Compare
@original-brownbear I've inlined the lambdas and added JSON parser microbenchmark - please see if it looks good. |
931194c
to
900da19
Compare
Thanks @smalyshev this looks quite nice. I could see this being a performance improvement as well actually from now reducing the code size in the hot path! Maybe wait for @rjernst to be good with this one as well but LGTM from my end! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks much better, but I have one more question
try { | ||
return createParser(config, jsonFactory.createParser(content)); | ||
} catch (CharConversionException e) { | ||
throw new XContentParseException(null, e.getMessage(), e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JsonFactory.createParser can throw JsonParseException, so shouldn't this catch also use handleParseException?
Ensures that all exception handling in the parser follows single code path and that JSON exceptions are handled in one place.