Skip to content

Commit 17fe447

Browse files
authored
Merge pull request #1 from N5N3/patch__
revert
2 parents 1d4dfee + 9de88bb commit 17fe447

File tree

2 files changed

+31
-23
lines changed

2 files changed

+31
-23
lines changed

base/abstractarray.jl

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,36 +1009,38 @@ end
10091009

10101010
function copyto_unaliased!(deststyle::IndexStyle, dest::AbstractArray, srcstyle::IndexStyle, src::AbstractArray)
10111011
isempty(src) && return dest
1012-
length(dest) >= length(src) || throw(BoundsError(dest, LinearIndices(src)))
1012+
destinds, srcinds = LinearIndices(dest), LinearIndices(src)
1013+
idf, isf = first(destinds), first(srcinds)
1014+
Δi = idf - isf
1015+
(checkbounds(Bool, destinds, isf+Δi) & checkbounds(Bool, destinds, last(srcinds)+Δi)) ||
1016+
throw(BoundsError(dest, srcinds))
10131017
if deststyle isa IndexLinear
10141018
if srcstyle isa IndexLinear
1015-
Δi = firstindex(dest) - firstindex(src)
1016-
for i in eachindex(src)
1017-
@inbounds dest[i + Δi] = src[i]
1019+
# Single-index implementation
1020+
@inbounds for i in srcinds
1021+
dest[i + Δi] = src[i]
10181022
end
10191023
else
1020-
j = firstindex(dest) - 1
1021-
@inbounds @simd for I in eachindex(src)
1022-
dest[j+=1] = src[I]
1024+
# Dual-index implementation
1025+
i = idf - 1
1026+
@inbounds for a in src
1027+
dest[i+=1] = a
10231028
end
10241029
end
10251030
else
1026-
if srcstyle isa IndexLinear
1027-
i = firstindex(src) - 1
1028-
@inbounds @simd for J in eachindex(dest)
1029-
dest[J] = src[i+=1]
1031+
iterdest, itersrc = eachindex(dest), eachindex(src)
1032+
if iterdest == itersrc
1033+
# Shared-iterator implementation
1034+
for I in iterdest
1035+
@inbounds dest[I] = src[I]
10301036
end
10311037
else
1032-
iterdest, itersrc = eachindex(dest), eachindex(src)
1033-
if iterdest == itersrc
1034-
# Shared-iterator implementation
1035-
@inbounds @simd for I in itersrc
1036-
dest[I] = src[I]
1037-
end
1038-
else
1039-
for (I,J) in zip(itersrc, iterdest)
1040-
@inbounds dest[J] = src[I]
1041-
end
1038+
# Dual-iterator implementation
1039+
ret = iterate(iterdest)
1040+
@inbounds for a in src
1041+
idx, state = ret
1042+
dest[idx] = a
1043+
ret = iterate(iterdest, state)
10421044
end
10431045
end
10441046
end

base/broadcast.jl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -991,11 +991,17 @@ preprocess_args(dest, args::Tuple{}) = ()
991991
# Specialize this method if all you want to do is specialize on typeof(dest)
992992
@inline function copyto!(dest::AbstractArray, bc::Broadcasted{Nothing})
993993
axes(dest) == axes(bc) || throwdm(axes(dest), axes(bc))
994-
# Performance optimization: broadcast!(identity, dest, A) is equivalent to copyto!(dest, A) if indices match
994+
# Performance optimization: broadcast!(identity, dest, A) is equivalent to copyto!(dest, A) if indices match.
995+
# However copyto!(dest, A) is very slow in many cases, implement a faster version here.
995996
if bc.f === identity && bc.args isa Tuple{AbstractArray} # only a single input argument to broadcast!
996997
A = bc.args[1]
997998
if axes(dest) == axes(A)
998-
return copyto!(dest, A)
999+
A′ = broadcast_unalias(dest, A)
1000+
iter = IndexStyle(dest) isa IndexCartesian ? dest : A′
1001+
@inbounds @simd for I in eachindex(iter)
1002+
dest[I] = A′[I]
1003+
end
1004+
return dest
9991005
end
10001006
end
10011007
bc′ = preprocess(dest, bc)

0 commit comments

Comments
 (0)