-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Closed
Labels
arrays[a, r, r, a, y, s][a, r, r, a, y, s]needs decisionA decision on this change is neededA decision on this change is needed
Description
When we introduced ReshapedArrays, we deferred making the breaking change where reshape(::Array, …) returns a ReshapedArray. I say we change that for 1.0.
There are two reasons to do this:
- Semantics. The wrapper makes it much more obvious that the data are shared (see, e.g., https://stackoverflow.com/questions/38777469/function-for-reshape-view), and the semantics are much more obviously "just" an indexing transformation into the parent. It seems like folks are getting used to all the array wrappers.
- Performance. We'll eventually add more optimizations for array wrappers, allowing them all to live on the stack (right?). ReshapedArray would ride along "for free" here, whereas enabling the same optimization for the C array header would be extra work. (I'm not in a position to estimate how much work — all I know is that it's work that few would be able to do.) This would put is in the unfortunate situation where
ReshapedArray(::Array, …)would be completely allocation-free whereasreshape(::Array, …)would not be. Either way, cursory benchmarks on 0.6 show the Julian ReshapedArray to already be faster than the C reshape on construction, and the two look to be comparable on access.
While breaking, I think it's only marginally so. Folks who expect f(reshape(A, 2,3,4)) to hit f(A::Array) would have to widen their signatures, and similarly for struct fields. Is there anything else?
Benchmarks are on 0.6 just because it was so much easier to do so with BenchmarkTools right now. We'll definitely need the Nanosoldier back on its feet for this one.
| | |_| | | | (_| | | Version 0.6.0 (2017-06-19 13:05 UTC)
_/ |\__'_|_|_|\__'_| | Official http://julialang.org/ release
|__/ | x86_64-apple-darwin13.4.0
julia> using BenchmarkTools
WARNING: Compat.UTF8String is deprecated, use String instead.
likely near /Users/mbauman/.julia/v0.6/JLD/src/JLD.jl:971
julia> # Base._reshape, but without the ::Array override
function reshape2(parent::AbstractArray, dims::Dims)
n = Base._length(parent)
prod(dims) == n || throw(DimensionMismatch("parent has $n elements, which is incompatible with size $dims"))
Base.__reshape((parent, IndexStyle(parent)), dims)
end
reshape2 (generic function with 1 method)
julia> A = rand(60);
julia> C = @btime reshape($A, (5,4,3));
48.178 ns (2 allocations: 112 bytes)
julia> J = @btime reshape2($A, (5,4,3));
19.855 ns (1 allocation: 48 bytes)
julia> @btime sum($C);
30.455 ns (0 allocations: 0 bytes)
julia> @btime sum($J);
30.113 ns (0 allocations: 0 bytes)
julia> A = rand(50, 4, 3);
julia> C = @btime reshape($A, (100, 6));
45.914 ns (2 allocations: 96 bytes)
julia> J = @btime reshape2($A, (100, 6));
17.994 ns (1 allocation: 32 bytes)
julia> @btime sum($C)
172.636 ns (0 allocations: 0 bytes)
290.51809277377106
julia> @btime sum($J)
172.978 ns (0 allocations: 0 bytes)
290.51809277377106
Sacha0, StefanKarpinski, Keno, wucutin and schneiderfelipeSacha0, StefanKarpinski and schneiderfelipe
Metadata
Metadata
Assignees
Labels
arrays[a, r, r, a, y, s][a, r, r, a, y, s]needs decisionA decision on this change is neededA decision on this change is needed