Skip to content
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

Merged
merged 3 commits into from Apr 22, 2024

Conversation

edwintorok
Copy link
Contributor

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):
Screenshot 2024-04-19 at 17 20 17

After: (Buffer.add_string completely gone, no more alloc_string, and the Sexpr.escape is narrower)
Screenshot 2024-04-19 at 17 19 53

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:
Screenshot 2024-04-19 at 17 41 17

@edwintorok edwintorok changed the title IH-553: Optimize Sexpr.escape IH-553: Optimize Sexpr.{escape,unescape} Apr 19, 2024
@edwintorok edwintorok marked this pull request as ready for review April 19, 2024 16:50
@psafont
Copy link
Member

psafont commented Apr 19, 2024

Can we target master branch here? :)

@edwintorok
Copy link
Contributor Author

I targeted perf because I wanted to do more testing, although there is not much that can go wrong here, so I can retarget.

@edwintorok edwintorok changed the base branch from feature/perf to master April 19, 2024 17:02
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>
)
s ;
Buffer.contents escaped
Buffer.add_char escaped c
Copy link
Member

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

@robhoes robhoes merged commit f1903aa into xapi-project:master Apr 22, 2024
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants