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
IH-553: Optimize Sexpr.{escape,unescape} #5576
Conversation
Can we target master branch here? :) |
I targeted perf because I wanted to do more testing, although there is not much that can go wrong here, so I can retarget. |
It was allocating a string for each character, only to then immediately add it to a buffer. Instead add the character to the buffer directly. The temporary string was probably created to factor out 'Buffer.add', but I'd rather copy Buffer.add 4x times than have the perf hit. Further optimizations might be possible here as the comments says, but this is a low-risk, obvious optimization. Signed-off-by: Edwin Török <edwin.torok@cloud.com>
Optimistically check for the presence of escape characters before escaping. This avoids rebuilding the string when escapable characters are not present (the common case). Signed-off-by: Edwin Török <edwin.torok@cloud.com>
Check for the presence of the escape character before rebuilding the string Signed-off-by: Edwin Török <edwin.torok@cloud.com>
ab4e8ce
to
6f15c30
Compare
) | ||
s ; | ||
Buffer.contents escaped | ||
Buffer.add_char escaped c |
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.
Just a question: would a pipe operator be of the same effect (no temporary variable)?
E.g.
(match c with ..) |> Buffer.add_string escaped
It was allocating a string for each character, only to then immediately add it to a buffer. Instead add the character to the buffer directly.
The temporary string was probably created to factor out 'Buffer.add', but I'd rather copy Buffer.add 4x times than have the perf hit.
Further optimizations might be possible here as the comments says, but this is a low-risk, obvious optimization.
Before (see how Buffer.add_string and caml_alloc_string take up quite a bit of time):
After: (Buffer.add_string completely gone, no more alloc_string, and the Sexpr.escape is narrower)
In fact we can take this a bit further and check for the presence of escapable characters when escaping and for the presence of the escape character when unescaping. Notice how Sexpr.escape is a lot narrower now, and Sexpr.unescape has disappeared from the flamegraph: