-
Notifications
You must be signed in to change notification settings - Fork 6
improve performance and memory usage in HashUtils.djb2 #28
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
Runtime profiling indicates this method generates several many memory allocations. Comparing to the JS implementation, we saw the intent of the `hash &= hash` line was to force the JS runtime to keep the number as a 32-bit integer. This is indeed the correct way to do it in JS, but not in Ruby; as a result, the `hash` local will grow ever larger, requiring more and more memory since Ruby supports unbounded integers. Fix: truncate the hash value on each iteration with the same 32-bit `0xFFFFFFF` constant used at the end instead.
Benchmarking before/after with a 256-char string on my laptop:
A quick, imprecise comparison by inspecting I spot-checked a handful of input values to ensure the output hash value did not change. |
Nice find! Pulling this in to run tests on it now |
@tore-statsig actually i just realized we can do even better — the only thing inside the each loop is |
#28 """ Runtime profiling indicates this method generates several many memory allocations. Comparing to the JS implementation, we saw the intent of the `hash &= hash` line was to force the JS runtime to keep the number as a 32-bit integer. This is indeed the correct way to do it in JS, but not in Ruby; as a result, the `hash` local will grow ever larger, requiring more and more memory since Ruby supports unbounded integers. Fix: truncate the hash value on each iteration with the same 32-bit `0xFFFFFFF` constant used at the end instead. """ Co-authored-by: Sam Kimbrel <[email protected]>
The original version of this is released https://github.com/statsig-io/ruby-sdk/releases/tag/2.4.2 |
great! we've been running the second commit (switching to |
the only thing inside the each loop is .ord, which is available as each_codepoint #28 --------- Co-authored-by: Sam Kimbrel <[email protected]>
Runtime profiling indicates this method generates several many memory allocations.
Comparing to the JS implementation, we saw the intent of the
hash &= hash
line was to force the JS runtime to keep the number as a 32-bit integer. This is indeed the correct way to do it in JS, but not in Ruby; as a result, thehash
local will grow ever larger, requiring more and more memory since Ruby supports unbounded integers.Fix: truncate the hash value on each iteration with the same 32-bit
0xFFFFFFF
constant used at the end instead.