-
-
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
Performance regression in vcat(::Vector, ::Number)
in v1.9
#50831
Comments
silly workaround is to replace julia> VERSION
v"1.8.4"
julia> i_vec = [i];
julia> @btime vcat($v, $i);
515.092 ns (1 allocation: 8.00 KiB)
julia> @btime vcat($v, $i_vec);
517.818 ns (1 allocation: 8.00 KiB)
julia> @btime vcat($v, [$i]);
532.624 ns (2 allocations: 8.06 KiB) julia> VERSION
v"1.9.2"
julia> i_vec = [i];
julia> @btime vcat($v, $i);
1.054 μs (13 allocations: 8.28 KiB)
julia> @btime vcat($v, $i_vec);
516.581 ns (1 allocation: 8.00 KiB)
julia> @btime vcat($v, [$i]);
543.651 ns (2 allocations: 8.06 KiB) julia> VERSION
v"1.10.0-beta1"
julia> @btime vcat($v, $i);
523.656 ns (1 allocation: 8.00 KiB)
julia> @btime vcat($v, $i_vec);
522.568 ns (1 allocation: 8.00 KiB)
julia> @btime vcat($v, [$i]);
544.312 ns (2 allocations: 8.06 KiB) EDIT: hmm, although this workaround doesn't seem to recover performance in my real use-case (which is a little tricky to reduce down... will work on it) |
Can we also try this as a workaround?: julia> @btime push!(copy($v), $i);
454.703 ns (2 allocations: 24.81 KiB) EDIT: thanks, i meant push not append 👍 |
vcat(::Vector, ::Number)
in v1.9vcat(::Vector, ::Number)
in v1.9
yes, So does julia> VERSION
v"1.8.4"
julia> @btime vcat($v, $i);
503.625 ns (1 allocation: 8.00 KiB)
julia> @btime push!(copy($v), $i);
472.148 ns (2 allocations: 24.81 KiB)
julia> @btime append!(copy($v), $i);
472.862 ns (2 allocations: 24.81 KiB)
julia> VERSION
v"1.9.2"
julia> @btime vcat($v, $i);
1.058 μs (13 allocations: 8.28 KiB)
julia> @btime push!(copy($v), $i);
483.031 ns (2 allocations: 24.81 KiB)
julia> @btime append!(copy($v), $i);
483.087 ns (2 allocations: 24.81 KiB) julia> VERSION
v"1.10.0-beta1"
julia> @btime vcat($v, $i);
521.052 ns (1 allocation: 8.00 KiB)
julia> @btime push!(copy($v), $i);
573.370 ns (2 allocations: 24.81 KiB)
julia> @btime append!(copy($v), $i);
579.710 ns (2 allocations: 24.81 KiB) |
(CC: @staticfloat for the above) |
@dkarrasch may know, as he authored the original PR. |
btw, for our real-use we just rolled our own function for now (and i'm sure there are other good ways to write this same thing): function vcat_element(v::Vector{T}, x::T) where T
len = length(v)
new_v = Vector{T}(undef, len + 1)
unsafe_copyto!(new_v, 1, v, 1, len)
new_v[end] = x
return new_v
end |
Also, i see a few other
Should we add some more |
More benchmarks sounds good. Also sorry I forgot to report back.. Bisect results were confusing as to finding which commit fixed this on the 1.10 branch. After looking more closely at the bisect log, I realized why it was confusing:
So either there was a bug during backporting, or somehow this commit was depending on something only present in 1.10 to make it effective. |
I'm not sure how best to find out what commits in 1.10 were needed for the original commit to not cause a regression? I guess we could do a bisect that replays the backport onto various commits inbetween 1.9 and 1.10 to see when it wouldn't have caused a regression? |
Okay, I ran that bisect! Here's the bisect scripts I used, in case it's helpful to anyone in the future: # Usage: ./bisect-script.sh <julia script>
# assert that the script is given
if [ -z "$1" ]; then
echo "Usage: ./bisect-script.sh <julia script>"
exit 1
fi
git cherry-pick -m1 e6c84a1eae1f75cad1c62f62f2074c0f1bf124d1 # <-- this was the extra part I added for this
make clean
make -j || (make cleanall; make -j)
./julia --startup=no $1 && (
git reset --hard HEAD~ # cleanup <-- also added this
exit 0
) || (
git reset --hard HEAD~ # cleanup <-- and this
exit 1
) @info VERSION
const v = collect(Any, 1:1000);
const i = 1;
using Test
f(i) = vcat(v, i)
# warmup
@test length(f(i)) == 1001
# final actual test
# NOTE: Swapped the test while bisecting for the fix. "failing" means it's fixed.
@test @allocations(f(i)) > 5 |
Bisect pointed to 1543cdd as the first commit inbetween 1.9 and 1.10, where backporting the vcat change doesn't introduce a regression. That's coming from #48720. I guess adding these two lines is what prevented the regression?: +checkindex(::Type{Bool}, inds::IdentityUnitRange, i::Real) = checkindex(Bool, inds.indices, i)
+checkindex(::Type{Bool}, inds::OneTo{T}, i::T) where {T<:BitInteger} = unsigned(i - one(i)) < unsigned(last(inds)) |
The question now is how to proceed. I'm very far away from this kind of performance tuning work. I see at least these two options:
Thanks!! |
If it fixes it, backporting #48720 doesnt seem so bad. |
I have confirmed that backporting #48720 fixes the regression locally. I'll mark it for backporting then. 👍 Thank you! |
... Do you understand why it fixes the regression? That would probably be good to understand before backporting, to ensure that we aren't introducing any other complexities? |
This should be fixed in 1.9.3. Leaving a note here for us to confirm. |
If I wanted to follow-up about adding some benchmarks related to |
Seems to be fixed in v1.10
v1.8
v1.9
v1.10
The text was updated successfully, but these errors were encountered: