From 253fa74996c19129dfa326de141e479a9e3150df Mon Sep 17 00:00:00 2001 From: Matt Bauman Date: Wed, 3 May 2017 14:36:06 -0500 Subject: [PATCH] Make reshape(::Bitarray,...) type stable (#21670) This works around some of the performance regressions flagged in #20993. The instability itself is not new nor is it the cause of the regression. The trouble is just that there are a few more inlined functions now, each of which needs a dynamic dispatch. It is worth noting that 0.6 (with this patch) is significantly faster than 0.5 (with this patch). I measure an improvement of ~30%. --- base/bitarray.jl | 7 +++++-- test/bitarray.jl | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/base/bitarray.jl b/base/bitarray.jl index 105d590c55f3a..265cf65b3614c 100644 --- a/base/bitarray.jl +++ b/base/bitarray.jl @@ -472,10 +472,13 @@ function copy!(dest::BitArray, src::Array) return unsafe_copy!(dest, 1, src, 1, length(src)) end -function reshape(B::BitArray, dims::NTuple{N,Int}) where N +function reshape(B::BitArray{N}, dims::NTuple{N,Int}) where N + return dims == size(B) ? B : _bitreshape(B, dims) +end +reshape(B::BitArray, dims::Tuple{Vararg{Int}}) = _bitreshape(B, dims) +function _bitreshape(B::BitArray, dims::NTuple{N,Int}) where N prod(dims) == length(B) || throw(DimensionMismatch("new dimensions $(dims) must be consistent with array size $(length(B))")) - dims == size(B) && return B Br = BitArray{N}(ntuple(i->0,Val{N})...) Br.chunks = B.chunks Br.len = prod(dims) diff --git a/test/bitarray.jl b/test/bitarray.jl index 9a0541ef7b92c..3ae22cb0beae3 100644 --- a/test/bitarray.jl +++ b/test/bitarray.jl @@ -143,6 +143,10 @@ timesofar("conversions") @check_bit_operation reshape(b1, (n2,n1)) BitMatrix @test_throws DimensionMismatch reshape(b1, (1,n1)) + @test @inferred(reshape(b1, n1*n2)) == @inferred(reshape(b1, (n1*n2,))) == @inferred(reshape(b1, Val{1})) == @inferred(reshape(b1, :)) + @test @inferred(reshape(b1, n1, n2)) === @inferred(reshape(b1, Val{2})) === b1 + @test @inferred(reshape(b1, n2, :)) == @inferred(reshape(b1, (n2, n1))) != @inferred(reshape(b1, Val{2})) + b1 = bitrand(s1, s2, s3, s4) @check_bit_operation reshape(b1, (s3,s1,s2,s4)) BitArray{4} @test_throws DimensionMismatch reshape(b1, (1,n1))