-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Reduce regexp memory use in tracestate #4664
Conversation
Codecov Report
@@ Coverage Diff @@
## main #4664 +/- ##
======================================
Coverage ? 81.7%
======================================
Files ? 225
Lines ? 18056
Branches ? 0
======================================
Hits ? 14762
Misses ? 2996
Partials ? 298
|
Could you run benchmark tests (maybe we need a new benchmark?) to show the actual memory difference? |
Sure. I loaded the relevant |
I am pretty sure that @dmathieu is asking for "Go Benchmarks". References: |
I added a simple benchmark and it shows a reduction in runtime from the old code:
New:
though of course the reduction in resident RAM usage is not captured in this. |
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.
Can you please update the PR description with the benchmark result from "before" and "after" the change?
If nobody will complain I will merge this PR on Monday. |
It turns out that the
regexp
implementation uses a fair amount of memory for counted repetitions of the form (e.g.)[a-z]{0,255}
, linear with the count (there is a documented maximum of 1000). Just 3 regexes intracestate.go
add over a megabyte of resident RAM usage for the library, owing to their usage of regex logic to enforce length caps on pieces of the tracestate syntax.This PR reduces the memory usage of those regexes by about a megabyte by having the regexes dictate acceptable character sequences but not length, and applying length checks after/outside the regexp. The runtime for both approaches should be similar; I've tried to minimize extra iterations over the parsed strings. I've also reduced the number of captures to the minimum required.
To share validation logic I had
parseMember
callnewMember
but to keep the exact behavior I had to transmute the returned errors. There may be a more idiomatic way to do this (not a golang expert) or it may be OK to subtly change behavior and I can drop that requirement to simplify the code.Update: I added benchmarks to show that runtime performance has improved in addition to the resident RAM savings:
Old:
New:
I want to thank the creators of
tracestate_test.go
for the excellent test suite!