-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Remove unnecessary allocation in BitSet()
#49461
Conversation
This works with julia> @btime begin x = sizehint!(zeros(UInt64, 0), 4); for _ in 1:3; Base._growbeg!(x, 1); end; end
52.379 ns (2 allocations: 144 bytes)
julia> @btime begin x = resize!(Vector{UInt64}(undef, 4), 0); for _ in 1:3; Base._growbeg!(x, 1); end; end
43.264 ns (1 allocation: 96 bytes) |
The benchmarks are unfair there, since you never use a large enough workload to show the higher wasted memory of this change. It is not large waste, so it might be fine if BitSet is normally less than 256. Otherwise this may be worse. |
I did not realize that In addition to the obvious change here (eliminating a never-used 0-size allocation) I also unwittingly changed the preallocation size from 8 (512) to 4 (256). FWIW, I imagine the intent of this code was to preallocate 4, not 8. Here are some more comprehensive benchmarks in case we would like to put the preallocation size back to 8. julia> for n in 1:17
println(n)
print("Old (0 + 8)"); @btime begin x = sizehint!(zeros(UInt64, 0), 4); for i in 1:$n; push!(x, i); end; end
print("New (4) "); @btime begin x = resize!(Vector{UInt64}(undef, 4), 0); for i in 1:$n; push!(x, i); end; end
print("New (8) "); @btime begin x = resize!(Vector{UInt64}(undef, 8), 0); for i in 1:$n; push!(x, i); end; end
end
1
Old (0 + 8) 35.876 ns (2 allocations: 144 bytes)
New (4) 22.799 ns (1 allocation: 96 bytes)
New (8) 23.301 ns (1 allocation: 128 bytes)
2
Old (0 + 8) 41.708 ns (2 allocations: 144 bytes)
New (4) 29.397 ns (1 allocation: 96 bytes)
New (8) 30.025 ns (1 allocation: 128 bytes)
3
Old (0 + 8) 45.033 ns (2 allocations: 144 bytes)
New (4) 32.067 ns (1 allocation: 96 bytes)
New (8) 33.744 ns (1 allocation: 128 bytes)
4
Old (0 + 8) 48.415 ns (2 allocations: 144 bytes)
New (4) 35.373 ns (1 allocation: 96 bytes)
New (8) 36.631 ns (1 allocation: 128 bytes)
5
Old (0 + 8) 51.882 ns (2 allocations: 144 bytes)
New (4) 51.534 ns (2 allocations: 176 bytes)
New (8) 40.154 ns (1 allocation: 128 bytes)
6
Old (0 + 8) 54.894 ns (2 allocations: 144 bytes)
New (4) 55.415 ns (2 allocations: 176 bytes)
New (8) 42.717 ns (1 allocation: 128 bytes)
7
Old (0 + 8) 57.546 ns (2 allocations: 144 bytes)
New (4) 57.546 ns (2 allocations: 176 bytes)
New (8) 45.707 ns (1 allocation: 128 bytes)
8
Old (0 + 8) 60.572 ns (2 allocations: 144 bytes)
New (4) 60.213 ns (2 allocations: 176 bytes)
New (8) 48.745 ns (1 allocation: 128 bytes)
9
Old (0 + 8) 74.169 ns (3 allocations: 480 bytes)
New (4) 74.368 ns (3 allocations: 512 bytes)
New (8) 63.115 ns (2 allocations: 464 bytes)
10
Old (0 + 8) 78.727 ns (3 allocations: 480 bytes)
New (4) 77.809 ns (3 allocations: 512 bytes)
New (8) 66.973 ns (2 allocations: 464 bytes)
11
Old (0 + 8) 81.828 ns (3 allocations: 480 bytes)
New (4) 80.708 ns (3 allocations: 512 bytes)
New (8) 69.842 ns (2 allocations: 464 bytes)
12
Old (0 + 8) 84.540 ns (3 allocations: 480 bytes)
New (4) 84.410 ns (3 allocations: 512 bytes)
New (8) 72.522 ns (2 allocations: 464 bytes)
13
Old (0 + 8) 87.578 ns (3 allocations: 480 bytes)
New (4) 87.578 ns (3 allocations: 512 bytes)
New (8) 76.303 ns (2 allocations: 464 bytes)
14
Old (0 + 8) 90.133 ns (3 allocations: 480 bytes)
New (4) 90.234 ns (3 allocations: 512 bytes)
New (8) 78.866 ns (2 allocations: 464 bytes)
15
Old (0 + 8) 92.831 ns (3 allocations: 480 bytes)
New (4) 93.498 ns (3 allocations: 512 bytes)
New (8) 82.601 ns (2 allocations: 464 bytes)
16
Old (0 + 8) 96.373 ns (3 allocations: 480 bytes)
New (4) 96.228 ns (3 allocations: 512 bytes)
New (8) 85.019 ns (2 allocations: 464 bytes)
17
Old (0 + 8) 101.901 ns (3 allocations: 480 bytes)
New (4) 100.449 ns (3 allocations: 512 bytes)
New (8) 90.227 ns (2 allocations: 464 bytes) |
resized memory can be freed later. The initial allocation cannot be freed later |
Instead of allocating a vector of size 0 and then reallocating of size 4, skip straight to the larger allocation.