Skip to content

Commit

Permalink
Ensure checksize inlines
Browse files Browse the repository at this point in the history
In JuliaLang#13612 I converted checksize from a generated function to a recursive lispy definition, but the methods are too complicated to be automatically inlined. Manually adding the inline annotation fixes this performance regression JuliaLang#14594. Master is now faster than 0.4.0 on most of the array perf tests.
  • Loading branch information
mbauman committed Jan 8, 2016
1 parent ce1e856 commit 1f6dadd
Showing 1 changed file with 14 additions and 7 deletions.
21 changes: 14 additions & 7 deletions base/multidimensional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -247,18 +247,25 @@ end
end

# checksize ensures the output array A is the correct size for the given indices
@noinline throw_checksize_error(arr, dim, idx) = throw(DimensionMismatch("index $d selects $(length(I[d])) elements, but size(A, $d) = $(size(A,d))"))
@noinline throw_checksize_error(A, dim, idx) = throw(DimensionMismatch("index $dim selects $(length(idx)) elements, but size(A, $dim) = $(size(A,dim))"))
@noinline throw_checksize_error(A, dim, idx::AbstractArray{Bool}) = throw(DimensionMismatch("index $dim selects $(sum(idx)) elements, but size(A, $dim) = $(size(A,dim))"))

checksize(A::AbstractArray, I::AbstractArray) = size(A) == size(I) || throw_checksize_error(A, 1, I)
checksize(A::AbstractArray, I::AbstractArray{Bool}) = length(A) == sum(I) || throw_checksize_error(A, 1, I)

checksize(A::AbstractArray, I...) = _checksize(A, 1, I...)
@inline checksize(A::AbstractArray, I...) = _checksize(A, 1, I...)
_checksize(A::AbstractArray, dim) = true
# Skip scalars
_checksize(A::AbstractArray, dim, ::Real, J...) = _checksize(A, dim, J...)
_checksize(A::AbstractArray, dim, I, J...) = (size(A, dim) == length(I) || throw_checksize_error(A, dim, I); _checksize(A, dim+1, J...))
_checksize(A::AbstractArray, dim, I::AbstractVector{Bool}, J...) = (size(A, dim) == sum(I) || throw_checksize_error(A, dim, I); _checksize(A, dim+1, J...))
_checksize(A::AbstractArray, dim, ::Colon, J...) = _checksize(A, dim+1, J...)
# Drop dimensions indexed by scalars, ignore colons
@inline _checksize(A::AbstractArray, dim, ::Real, J...) = _checksize(A, dim, J...)
@inline _checksize(A::AbstractArray, dim, ::Colon, J...) = _checksize(A, dim+1, J...)
@inline function _checksize(A::AbstractArray, dim, I, J...)
size(A, dim) == length(I) || throw_checksize_error(A, dim, I)
_checksize(A, dim+1, J...)
end
@inline function _checksize(A::AbstractArray, dim, I::AbstractVector{Bool}, J...)
size(A, dim) == sum(I) || throw_checksize_error(A, dim, I)
_checksize(A, dim+1, J...)
end

@inline unsafe_setindex!(v::BitArray, x::Bool, ind::Int) = (Base.unsafe_bitsetindex!(v.chunks, x, ind); v)
@inline unsafe_setindex!(v::BitArray, x, ind::Real) = (Base.unsafe_bitsetindex!(v.chunks, convert(Bool, x), to_index(ind)); v)
Expand Down

0 comments on commit 1f6dadd

Please sign in to comment.