Skip to content

Commit 5e09f12

Browse files
authored
inline OffsetArray constructors (#164)
This reduces the overhead when constructing an OffsetArray
1 parent 08f969b commit 5e09f12

File tree

1 file changed

+16
-15
lines changed

1 file changed

+16
-15
lines changed

src/OffsetArrays.jl

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ struct OffsetArray{T,N,AA<:AbstractArray{T,N}} <: AbstractArray{T,N}
9393
parent::AA
9494
offsets::NTuple{N,Int}
9595
function OffsetArray{T, N, AA}(parent::AA, offsets::NTuple{N, Int}) where {T, N, AA<:AbstractArray{T,N}}
96-
@boundscheck overflow_check.(axes(parent), offsets)
96+
# allocation of `map` on tuple is optimized away
97+
map(overflow_check, axes(parent), offsets)
9798
new{T, N, AA}(parent, offsets)
9899
end
99100
end
@@ -126,40 +127,40 @@ end
126127

127128
# Tuples of integers are treated as offsets
128129
# Empty Tuples are handled here
129-
function OffsetArray(A::AbstractArray, offsets::Tuple{Vararg{Integer}})
130+
@inline function OffsetArray(A::AbstractArray, offsets::Tuple{Vararg{Integer}})
130131
_checkindices(A, offsets, "offsets")
131132
OffsetArray{eltype(A), ndims(A), typeof(A)}(A, offsets)
132133
end
133134

134135
# These methods are necessary to disallow incompatible dimensions for
135136
# the OffsetVector and the OffsetMatrix constructors
136137
for (FT, ND) in ((:OffsetVector, :1), (:OffsetMatrix, :2))
137-
@eval function $FT(A::AbstractArray{<:Any,$ND}, offsets::Tuple{Vararg{Integer}})
138+
@eval @inline function $FT(A::AbstractArray{<:Any,$ND}, offsets::Tuple{Vararg{Integer}})
138139
_checkindices(A, offsets, "offsets")
139140
OffsetArray{eltype(A), $ND, typeof(A)}(A, offsets)
140141
end
141142
FTstr = string(FT)
142-
@eval function $FT(A::AbstractArray, offsets::Tuple{Vararg{Integer}})
143+
@eval @inline function $FT(A::AbstractArray, offsets::Tuple{Vararg{Integer}})
143144
throw(ArgumentError($FTstr*" requires a "*string($ND)*"D array"))
144145
end
145146
end
146147

147148
## OffsetArray constructors
148149
for FT in (:OffsetArray, :OffsetVector, :OffsetMatrix)
149150
# Nested OffsetArrays may strip off the wrapper and collate the offsets
150-
@eval function $FT(A::OffsetArray, offsets::Tuple{Vararg{Integer}})
151+
@eval @inline function $FT(A::OffsetArray, offsets::Tuple{Vararg{Integer}})
151152
_checkindices(A, offsets, "offsets")
152153
$FT(parent(A), map(+, A.offsets, offsets))
153154
end
154155

155156
# In general, indices get converted to AbstractUnitRanges.
156157
# CartesianIndices{N} get converted to N ranges
157-
@eval function $FT(A::AbstractArray, inds::Tuple{Any,Vararg{Any}})
158+
@eval @inline function $FT(A::AbstractArray, inds::Tuple{Any,Vararg{Any}})
158159
$FT(A, _toAbstractUnitRanges(to_indices(A, axes(A), inds)))
159160
end
160161

161162
# convert ranges to offsets
162-
@eval function $FT(A::AbstractArray, inds::Tuple{AbstractUnitRange,Vararg{AbstractUnitRange}})
163+
@eval @inline function $FT(A::AbstractArray, inds::Tuple{AbstractUnitRange,Vararg{AbstractUnitRange}})
163164
_checkindices(A, inds, "indices")
164165
# Performance gain by wrapping the error in a function: see https://github.com/JuliaLang/julia/issues/37558
165166
throw_dimerr(lA, lI) = throw(DimensionMismatch("supplied axes do not agree with the size of the array (got size $lA for the array and $lI for the indices"))
@@ -169,27 +170,27 @@ for FT in (:OffsetArray, :OffsetVector, :OffsetMatrix)
169170
$FT(A, map(_offset, axes(A), inds))
170171
end
171172

172-
@eval $FT(A::AbstractArray, inds::Vararg) = $FT(A, inds)
173+
@eval @inline $FT(A::AbstractArray, inds::Vararg) = $FT(A, inds)
173174

174-
@eval $FT(A::AbstractArray, origin::Origin) = $FT(A, origin(A))
175+
@eval @inline $FT(A::AbstractArray, origin::Origin) = $FT(A, origin(A))
175176
end
176177

177178
# array initialization
178-
function OffsetArray{T,N}(init::ArrayInitializer, inds::Tuple{Vararg{OffsetAxisKnownLength}}) where {T,N}
179+
@inline function OffsetArray{T,N}(init::ArrayInitializer, inds::Tuple{Vararg{OffsetAxisKnownLength}}) where {T,N}
179180
_checkindices(N, inds, "indices")
180181
AA = Array{T,N}(init, map(_indexlength, inds))
181182
OffsetArray{T, N, typeof(AA)}(AA, map(_indexoffset, inds))
182183
end
183-
function OffsetArray{T, N}(init::ArrayInitializer, inds::Tuple) where {T, N}
184+
@inline function OffsetArray{T, N}(init::ArrayInitializer, inds::Tuple) where {T, N}
184185
OffsetArray{T, N}(init, _toAbstractUnitRanges(inds))
185186
end
186-
OffsetArray{T,N}(init::ArrayInitializer, inds::Vararg) where {T,N} = OffsetArray{T,N}(init, inds)
187+
@inline OffsetArray{T,N}(init::ArrayInitializer, inds::Vararg) where {T,N} = OffsetArray{T,N}(init, inds)
187188

188-
OffsetArray{T}(init::ArrayInitializer, inds::NTuple{N, OffsetAxisKnownLength}) where {T,N} = OffsetArray{T,N}(init, inds)
189-
function OffsetArray{T}(init::ArrayInitializer, inds::Tuple) where {T}
189+
@inline OffsetArray{T}(init::ArrayInitializer, inds::NTuple{N, OffsetAxisKnownLength}) where {T,N} = OffsetArray{T,N}(init, inds)
190+
@inline function OffsetArray{T}(init::ArrayInitializer, inds::Tuple) where {T}
190191
OffsetArray{T}(init, _toAbstractUnitRanges(inds))
191192
end
192-
OffsetArray{T}(init::ArrayInitializer, inds::Vararg) where {T} = OffsetArray{T}(init, inds)
193+
@inline OffsetArray{T}(init::ArrayInitializer, inds::Vararg) where {T} = OffsetArray{T}(init, inds)
193194

194195
Base.IndexStyle(::Type{OA}) where {OA<:OffsetArray} = IndexStyle(parenttype(OA))
195196
parenttype(::Type{OffsetArray{T,N,AA}}) where {T,N,AA} = AA

0 commit comments

Comments
 (0)