-
-
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
sum(function, tuple) is slow #30465
Comments
#30421, they use different summation implementation. |
Maybe we should have a specialized |
@KristofferC Here I don't have a |
I think that when you do |
No, it calls sum(x::Tuple{Any, Vararg{Any}}) = +(x...) |
What about defining:
|
This allocates for some reason. Any ideas? julia> sum1(f, x::Tuple}) = +(f.(x)...)
julia> @btime sum1(sin, (1.,2.,3.,4.,5.))
562.674 ns (10 allocations: 288 bytes)
0.1761616497223787
julia> @btime sum(sin, (1.,2.,3.,4.,5.))
56.020 ns (0 allocations: 0 bytes)
0.1761616497223787 |
Probably sufficiently large tuples get heap-allocated? |
julia> @btime sum1(sin, (1.,2.))
20.082 ns (0 allocations: 0 bytes)
1.7507684116335782
julia> @btime sum1(sin, (1.,2.,3.))
30.955 ns (0 allocations: 0 bytes)
1.8918884196934453
julia> @btime sum1(sin, (1.,2.,3.,4.))
40.153 ns (0 allocations: 0 bytes)
1.1350859243855171
julia> @btime sum1(sin, (1.,2.,3.,4.,5.))
474.749 ns (10 allocations: 288 bytes)
0.1761616497223787 I don't understand this. |
I don't know why the threshold is a 5-tuple, but suppose you have a tuple of 1000 elements — where would the result of |
I think there should be no temporary tuple at all. The operation can be done in-place. |
It seems too optimistic to hope that the compiler should always be able to figure out that it can eliminate the tuple construction. The following is based on the mapafoldl(F,op,a) = F(a)
mapafoldl(F,op,a,b) = op(F(a),F(b))
mapafoldl(F,op,a,b,c...) = op(op(F(a),F(b)), mapafoldl(F, op, c...))
function mapafoldl(F,op,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,qs...)
y = op(op(op(op(op(op(op(op(op(op(op(op(op(op(op(F(a),F(b)),F(c)),F(d)),F(e)),F(f)),F(g)),F(h)),F(i)),F(j)),F(k)),F(l)),F(m)),F(n)),F(o)),F(p))
for x in qs; y = op(y,F(x)); end
y
end
mysum(f, x::Tuple) = mapafoldl(f, +, x...) |
(Indeed, it seems like we could use the above to define an efficient |
(Note that the above is not quite right for a general |
should probably be
to avoid the unnecessary materialization. |
I don't think it matters for tuples, no allocation happens anyway. |
You have an argument of type
|
@chethega I don't understand the difference. I thought |
It works the same w.r.t dispatch but it forces specialization on the argument. |
gsum
should not be so slow compared tohsum
, right?The text was updated successfully, but these errors were encountered: