Skip to content

Commit

Permalink
Merge pull request #16865 from pabloferz/pz/unsafeind
Browse files Browse the repository at this point in the history
Better indexing for coupled iteration of array with AbstractArray{Bool}
  • Loading branch information
timholy authored Jun 11, 2016
2 parents 9471b97 + 2cd5ed4 commit feb9117
Showing 1 changed file with 40 additions and 3 deletions.
43 changes: 40 additions & 3 deletions base/multidimensional.jl
Original file line number Diff line number Diff line change
Expand Up @@ -301,16 +301,34 @@ function _unsafe_getindex(::LinearIndexing, src::AbstractArray, I::AbstractArray

D = eachindex(dest)
Ds = start(D)
for (i, s) in zip(eachindex(I), eachindex(src))
@inbounds Ii = I[i]
if Ii
for (b, s) in zip(I, eachindex(src))
if b
d, Ds = next(D, Ds)
@inbounds dest[d] = src[s]
end
end
dest
end

# specialized form for LinearFast
function _unsafe_getindex(::LinearFast, src::AbstractArray, I::AbstractArray{Bool})
shape = index_shape(src, I)
dest = similar(src, shape)
size(dest) == shape || throw_checksize_error(dest, shape)

D = eachindex(dest)
Ds = start(D)
s = 0
for i in eachindex(I)
s += 1
@inbounds if I[i]
d, Ds = next(D, Ds)
dest[d] = src[s]
end
end
dest
end

# Always index with the exactly indices provided.
@generated function _unsafe_getindex!(dest::AbstractArray, src::AbstractArray, I::Union{Real, AbstractArray, Colon}...)
N = length(I)
Expand Down Expand Up @@ -372,6 +390,25 @@ function _unsafe_setindex!(::LinearIndexing, A::AbstractArray, x, I::AbstractArr
A
end

# specialized form for LinearFast
function _unsafe_setindex!(::LinearFast, A::AbstractArray, x, I::AbstractArray{Bool})
X = _iterable(x)
Xs = start(X)
iA = 0
c = 0
for i in eachindex(I)
iA += 1
@inbounds if I[i]
done(X, Xs) && throw_setindex_mismatch(x, c+1)
(v, Xs) = next(X, Xs)
A[iA] = v
c += 1
end
end
setindex_shape_check(X, c)
A
end

@generated function _unsafe_batchsetindex!(A::AbstractArray, X, I::Union{Real,AbstractArray,Colon}...)
N = length(I)
quote
Expand Down

2 comments on commit feb9117

@nanosoldier
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Executing the daily benchmark build, I will reply here when finished:

@nanosoldier runbenchmarks(ALL, isdaily = true)

@nanosoldier
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your benchmark job has completed - possible performance regressions were detected. A full report can be found here. cc @jrevels

Please sign in to comment.