-
-
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
Improve performance of generic dot products #27678
Conversation
stdlib/LinearAlgebra/src/generic.jl
Outdated
@@ -663,29 +648,23 @@ julia> dot(x, y) | |||
function dot(x, y) # arbitrary iterables | |||
ix = iterate(x) | |||
iy = iterate(y) | |||
if ix === nothing | |||
if iy !== nothing | |||
if ix == nothing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why ==
everywhere?
W.r.t. # in dot1
if (ix == nothing) || (iy == nothing)
break
end It turns out to be necessary to write # in dot1
ix === nothing && break
iy === nothing && break It's not enough to just replace The # in dot2
while true
ix === nothing && break
iy === nothing && break
s += dot(ix[1], iy[1])
ix = iterate(x, ix[2])
iy = iterate(y, iy[2])
end With these changes things are faster again: julia> test(Float64, 100)
"Dot product using BLAS."
35.675 ns (0 allocations: 0 bytes)
"New generic dot product."
275.774 ns (0 allocations: 0 bytes)
"Generic dot product in LinearAlgebra/src/generic.jl."
216.415 ns (0 allocations: 0 bytes)
"Dot product for `AbstractVector`s in LinearAlgebra/src/generic.jl."
202.356 ns (0 allocations: 0 bytes)
"Dot product for `AbstractArray`s in LinearAlgebra/src/generic.jl."
109.182 ns (0 allocations: 0 bytes) |
Thank you very much, @haampie. I've replaced |
I don't think the test failures on appveyor and circleci are influenced by this PR. Should I make any additional changes in order to allow merging of this PR? |
s += dot(ix[1], iy[1]) | ||
ix = iterate(x, ix[2]) | ||
iy = iterate(y, iy[2]) | ||
s = zero(dot(first(x), first(y))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems the only potential downside to this implementation is that it retrieves the first element of each of x
and y
twice, rather than once with the explicit iterate
implementations?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally lgtm! :)
(I remain curious about the roughly factor-of-two performance difference between the two best generic implementations.)
Due to some recent work on dot products in Julia (#27401 and #27677), I'm interested in the generic implementations of those functions. Here are some benchmark result using the recent master branch of Julia:
There seem to be some serious type stability issues for the generic dot product in LinearAlgebra/src/generic.jl. Moreover, the generic dot product for
AbstractArray
s seems to be superior to the one forAbstractVector
s. Thus, I've added a new generic dot product and have removed the generic one forAbstractVector
s.