-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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 |
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-4294967295will run perfectly fine on virtually all platforms, and allocates only 2 MiB.uushuf -n10 -r -i0-4294967295immediately 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/nullbecomes 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/nulldidn't change (as expected)Benchmark
-r -n 10000000 -i 0-1000 > /dev/nullbecomes 438 % fasterNew benchmark
-n 100 -i 1000-2000000000 > /dev/nullbecomes +Inf % faster