-
-
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
Add Tuple(::CartesianIndex)
#23719
Add Tuple(::CartesianIndex)
#23719
Conversation
Historically I've opposed this change simply as a means of avoiding a major (and unfortunately very natural) performance trap: julia> Base.eltype(index::CartesianIndex) = eltype(index.I)
julia> Base.start(index::CartesianIndex) = start(index.I)
julia> Base.next(index::CartesianIndex, state) = next(index.I, state)
julia> Base.done(index::CartesianIndex, state) = done(index.I, state)
julia> function mysum1(A)
s = 0.0
@inbounds for i in CartesianRange(indices(A))
s += A[i]
end
s
end
mysum1 (generic function with 1 method)
julia> function mysum2(A)
s = 0.0
@inbounds for i in CartesianRange(indices(A))
s += A[i...]
end
s
end
mysum2 (generic function with 1 method)
julia> A = rand(10,10,10,10,10,10);
# after warmup (@btime is broken on master)
julia> @time mysum1(A)
0.003628 seconds (5 allocations: 176 bytes)
500411.4240107683
julia> @time mysum2(A)
1.641540 seconds (15.00 M allocations: 686.646 MiB, 5.57% gc time)
500411.4240107683 However, given that a version using |
Ah, yes, that's a bad trap. Though possible, I'd rather not add a special case/hack to inference. The much nicer and more general approach would be to add sufficient constant propagation to figure out cases where the length of the object to be splatted is known at compile time and then do the same inlining as for So for now, I guess we'd have to decide between convenience and avoiding a performance pitfall. |
Could just defining
Edit: I suppose it doesn't solve the destructuring problem. :-\ |
I guess my viewpoint is that since it's easy to destructure with |
So would we advertise |
I like the |
ca2446e
to
ae256f7
Compare
Tuple(::CartesianIndex)
Ok, changed the PR to only add the |
Make iterating a CartesianIndex equivalent to iterating the tuple it holds, being consistent with its indexing behavior. This is especially useful for destructuring as in e.g.i, j = indmax(A)
.Just add
Tuple(::CartesianIndex)
as per discussion below. Destructuring now would requirei, j = Tuple(indmax(A))
, but it's still possible without explicitly accessing theI
field.