-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
shuf: Fix OOM crash for huge number ranges #5980
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
Conversation
Fixes #1420. I can't believe I forgot to link that issue, that was the reason I was looking into |
c0069a5
to
c11ec11
Compare
Changes since last push:
|
c11ec11
to
7707771
Compare
7707771
to
db893a0
Compare
Changes since last push:
|
db893a0
to
d04c2d2
Compare
Changes since last push:
|
This requires special handling, because we cannot always generate all possible strings beforehand, e.g. in the case of "-n 2 -i 0-2147483647".
d04c2d2
to
f79dc64
Compare
Changes since last push:
EDIT: Nope, this definitely doesn't pass the |
<
8000
/tr>
f79dc64
to
f25b210
Compare
Changes since last push:
Seemingly-relevant output of `test_with_pr_core_utils_tests`The timestamp is pretty much the exact time at which the CI action ran, so it seems absolutely reasonable that by pure chance the right and left sides ran at sliiightly different fractions of a second, and straddled the tick of a second. Given how busy the CI machines are, that seems reasonable to me. (many empty lines removed)
|
excellent, thanks |
gnu_shuf -n10 -r -i0-4294967295
will run perfectly fine on virtually all platforms, and allocates only 2 MiB.uushuf -n10 -r -i0-4294967295
immediately OOMs withmemory allocation of 103079215104 bytes failed
, and probably needs at least 137 GiB of RAM and several hours if not weeks to actually work.This PR fixes this crash bug, by treating number ranges specially:
Vec<&[u8]>
and the "number range" concepts.The "special implementation" is a really stupid approach. I'm sure this can be optimized further (e.g. bitsets?), but first let's get this working at all. Also note that this will fix a failure in one of the GNU shuf tests.
Furthermore, observe how much faster it becomes even for "small" numbers, here running
{shuf} -n5 -i1-{upper_limit_like_50k}
:Raw `data.csv` of this graph, also zoomed out
All times measured by hyperfine using
hyperfine -N -w2 -L upperk 1,2,3,5,7,10,20,35,50,75,100,500 -L shuf "./gnu_shuf_9_4,./target/release_shuf_main_420dfe8a,./target/release_shuf_number_speed_g44877f96" --export-json shuf_hyperfine.json -- "{shuf} -i1-{upperk}000 -n5"
I believe the column order is:
I can tidy up and share the script I wrote which generated the above CSV from the JSON, if you'd like.
This affects one benchmarks negatively, and two strongly positively:
Benchmark
-i 0-10000000 > /dev/null
becomes 9-11 % slowerI believe this is an unavoidable trade-off between memory and speed. We could add another branch to just populate a
Vec<&[u8]>
like in the old days if the range is small enough, but then we will bikeshed about where to draw the line. I'll leave this work to someone else.Benchmark
input.txt > /dev/null
didn't change (as expected)Benchmark
-r -n 10000000 -i 0-1000 > /dev/null
becomes 438 % fasterNew benchmark
-n 100 -i 1000-2000000000 > /dev/null
becomes +Inf % faster