Skip to content

Commit

Permalink
Merge pull request #19943 from stevengj/fastpush
Browse files Browse the repository at this point in the history
improvements to push!, unshift!, append!, prepend!
  • Loading branch information
JeffBezanson authored Jan 12, 2017
2 parents 23b04b8 + 01be289 commit 84057ee
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 12 deletions.
37 changes: 32 additions & 5 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -554,15 +554,17 @@ function push!(a::Array{Any,1}, item::ANY)
end

function append!{T}(a::Array{T,1}, items::AbstractVector)
n = length(items)
itemindices = eachindex(items)
n = length(itemindices)
ccall(:jl_array_grow_end, Void, (Any, UInt), a, n)
copy!(a, length(a)-n+1, items, 1, n)
copy!(a, length(a)-n+1, items, first(itemindices), n)
return a
end

append!(a::Vector, iter) = _append!(a, iteratorsize(iter), iter)
push!(a::Vector, iter...) = append!(a, iter)

function _append!(a, ::HasLength, iter)
function _append!(a, ::Union{HasLength,HasShape}, iter)
n = length(a)
resize!(a, n+length(iter))
@inbounds for (i,item) in zip(n+1:length(a), iter)
Expand Down Expand Up @@ -591,17 +593,42 @@ julia> prepend!([3],[1,2])
3
```
"""
function prepend! end

function prepend!{T}(a::Array{T,1}, items::AbstractVector)
n = length(items)
itemindices = eachindex(items)
n = length(itemindices)
ccall(:jl_array_grow_beg, Void, (Any, UInt), a, n)
if a === items
copy!(a, 1, items, n+1, n)
else
copy!(a, 1, items, 1, n)
copy!(a, 1, items, first(itemindices), n)
end
return a
end

prepend!(a::Vector, iter) = _prepend!(a, iteratorsize(iter), iter)
unshift!(a::Vector, iter...) = prepend!(a, iter)

function _prepend!(a, ::Union{HasLength,HasShape}, iter)
n = length(iter)
ccall(:jl_array_grow_beg, Void, (Any, UInt), a, n)
i = 0
for item in iter
@inbounds a[i += 1] = item
end
a
end
function _prepend!(a, ::IteratorSize, iter)
n = 0
for item in iter
n += 1
unshift!(a, item)
end
reverse!(a, 1, n)
a
end


"""
resize!(a::Vector, n::Integer) -> Vector
Expand Down
32 changes: 25 additions & 7 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1122,10 +1122,31 @@ A = [[i i; i i] for i=1:2]
@test cumsum(A) == Any[[1 1; 1 1], [3 3; 3 3]]
@test cumprod(A) == Any[[1 1; 1 1], [4 4; 4 4]]

# PR #4627
A = [1,2]
@test append!(A, A) == [1,2,1,2]
@test prepend!(A, A) == [1,2,1,2,1,2,1,2]
isdefined(Main, :TestHelpers) || eval(Main, :(include("TestHelpers.jl")))
using TestHelpers.OAs

@testset "prepend/append" begin
# PR #4627
A = [1,2]
@test append!(A, A) == [1,2,1,2]
@test prepend!(A, A) == [1,2,1,2,1,2,1,2]

# iterators with length:
@test append!([1,2], (9,8)) == [1,2,9,8] == push!([1,2], (9,8)...)
@test prepend!([1,2], (9,8)) == [9,8,1,2] == unshift!([1,2], (9,8)...)
@test append!([1,2], ()) == [1,2] == prepend!([1,2], ())
# iterators without length:
g = (i for i = 1:10 if iseven(i))
@test append!([1,2], g) == [1,2,2,4,6,8,10] == push!([1,2], g...)
@test prepend!([1,2], g) == [2,4,6,8,10,1,2] == unshift!([1,2], g...)
g = (i for i = 1:2:10 if iseven(i)) # isempty(g) == true
@test append!([1,2], g) == [1,2] == push!([1,2], g...)
@test prepend!([1,2], g) == [1,2] == unshift!([1,2], g...)

# offset array
@test append!([1,2], OffsetArray([9,8], (-3,))) == [1,2,9,8]
@test prepend!([1,2], OffsetArray([9,8], (-3,))) == [9,8,1,2]
end

A = [1,2]
s = Set([1,2,3])
Expand Down Expand Up @@ -1880,9 +1901,6 @@ end
end
end

isdefined(Main, :TestHelpers) || eval(Main, :(include("TestHelpers.jl")))
using TestHelpers.OAs

@testset "accumulate, accumulate!" begin

@test accumulate(+, [1,2,3]) == [1, 3, 6]
Expand Down

0 comments on commit 84057ee

Please sign in to comment.