-
-
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
Use map instead of broadcast for Array*/Number and Matrix+-Matrix. #22208
base: master
Are you sure you want to change the base?
Conversation
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.
At first blush this looks good and sounds wise! :)
@nanosoldier |
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @jrevels |
Hm. julia> @btime map(+, x, x) setup = (x = randn(5));
56.961 ns (3 allocations: 176 bytes)
julia> @btime broadcast(+, x, x) setup = (x = randn(5));
33.672 ns (1 allocation: 128 bytes) Update: Now I remember. Base's |
IIRC there was an attempt for changing this previously and the performance difference was precisely the reason for keeping |
In the |
Man. I can't remember what I did half a year ago. Thanks for reminding me. I think we should try to make indices.jl
array.jl
A method error occurred before the base MethodError type was defined. Aborting...
typeof(Core.Inference.getindex)() world 1605
(Array{Any, 1}[
Expr(:call, :collect, Expr(:::, :itr, :Generator)::Any)::Any,
Expr(:block, Expr(:line, 427, :array.jl)::Any, :isz = Expr(:call, :iteratorsize, Expr(:., :itr, Expr(:quote, :iter)::Any)::Any)::Any, Expr(:line, 428, :array.jl)::Any, :et = Expr(:call, :_default_eltype, Expr(:call, :typeof, :itr)::Any)::Any, Expr(:line, 429, :array.jl)::Any, Expr(:if, Expr(:call, :isa, :isz, :SizeUnknown)::Any, Expr(:block, Expr(:line, 430, :array.jl)::Any, Expr(:return, Expr(:call, :grow_to!, Expr(:call, Expr(:curly, :Array, :et, 1)::Any, 0)::Any, :itr)::Any)::Any)::Any, Expr(:block, Expr(:line, 432, :array.jl)::Any, :st = Expr(:call, :start, :itr)::Any, Expr(:line, 433, :array.jl)::Any, Expr(:if, Expr(:call, :done, :itr, :st)::Any, Expr(:block, Expr(:line, 434, :array.jl)::Any, Expr(:return, Expr(:call, :_array_for, :et, Expr(:., :itr, Expr(:quote, :iter)::Any)::Any, :isz)::Any)::Any)::Any)::Any, Expr(:line, 436, :array.jl)::Any, Expr(:tuple, :v1, :st)::Any = Expr(:call, :next, :itr, :st)::Any, Expr(:line, 437, :array.jl)::Any, Expr(:call, :collect_to_with_first!, Expr(:call, :_array_for, Expr(:call, :typeof, :v1)::Any, Expr(:., :itr, Expr(:quote, :iter)::Any)::Any, :isz)::Any, :v1, :itr, :st)::Any)::Any)::Any)::Any], 2)
while loading array.jl, in expression starting on line 426
rec_backtrace at /Users/andreasnoack/julia-dev/src/stackwalk.c:84
jl_method_error_bare at /Users/andreasnoack/julia-dev/src/gf.c:1476 |
Maybe we should just define map(f::F where F, A::AbstractArray) = broadcast(f, A)
map(f::F where F, A::AbstractArray, B::AbstractArray) = broadcast(f, A, B) since they are the most important to optimize and the ones used for the definitions in this PR. Any other suggestions? |
Perhaps |
map with 2 array inputs needs to check that they are the same size, broadcast is more permissive |
This makes it easier to implement these methods for custom array types since map is much simpler than broadcast
It looks like there is no longer a performance penalty for using @nanosoldier |
@@ -24,7 +24,7 @@ julia> A | |||
2-2im 3-1im | |||
``` | |||
""" | |||
conj!(A::AbstractArray{<:Number}) = (@inbounds broadcast!(conj, A, A); A) | |||
conj!(A::AbstractArray{<:Number}) = (@inbounds map!(conj, A, A); A) |
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.
conj!(A::AbstractArray{<:Number}) = (@inbounds map!(conj, A, A); A) | |
conj!(A::AbstractArray{<:Number}) = (map!(conj, A, A); A) |
This caller doesn't know anything more than map!
does (and I don't think map!
uses a @boundscheck
in any case).
The one case where I could see there being a possible perf impact would be |
Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @ararslan |
This makes it easier to implement these methods for custom array
types since map is much simpler than broadcast.