Hi,
I was wondering if it exists an efficient implementation of popfirst!
for an array that allows a n
argument to request multiple pops at once (instead of calling popfirst!
n times).
Like popfirst!(a::Array, n::Int = 1)
If not, is there a reason that this can’t be done efficiently ?
1 Like
What problem do you have with: [popfirst!(xs) for _ in 1:n]
?
mike
March 15, 2021, 12:06pm
3
deleteat!(a, 1:n)
might be efficient, I’ve not looked at the implementation, but I’d assume it’s slightly better.
2 Likes
It’s just that I don’t know if it’s efficient to do multiple calls like that instead of removing one by one.
Okay thanks, it will do the trick for what I need. I didn’t know deleteat accepts ranges.
It’s just that I don’t know if it’s efficient to do multiple calls like that instead of removing one by one.
It is efficient.
It will be a static dispatch.
and julia’s Vector
can efficiently grow and shrink at both ends.
Edit:
actually deleteat!
is much faster. Not sure why
julia> @btime [popfirst!(x) for _ in 1:1000] setup=(x=rand(1_000_000));
6.954 μs (1 allocation: 7.94 KiB)
julia> @btime deleteat!(x, 1:1000) setup=(x=rand(1_000_000));
136.274 ns (0 allocations: 0 bytes)
1 Like
mike
March 15, 2021, 12:14pm
7
Probably the lack of allocation since it’s not creating the comprehension?
oxinabox:
It is efficient.
Might be better to use foreach
since otherwise, you create a redundant vector.
But for this specific case, I would think deleteat!
be significantly faster since it should be O(1) instead of O(n).
2 Likes
Oh yeah, it doesn’t return the deleted elements.
It returns the remaining elements.
I assume though if you are using popfirst
you want the deleted elements.
(also why can’t use foreach
).
Well, not in my case but it’s true that it could be.
mike
March 15, 2021, 12:20pm
11
Yeah, true, probably saving x[1:n]
prior to deleteat!
would be a better option then, maybe:
julia> function popnfirst!(xs, n)
out = xs[1:n]
deleteat!(xs, 1:n)
return out
end
1 Like
Do you think it would be worth doing a PR in Base.array.jl ?
It could even be a new method for popfirst!() to avoid a new name.
1 Like
mike
March 15, 2021, 12:29pm
13
splice!
may be what you want actually…
julia> splice!([1, 2, 3, 4, 5], 1:3)
3-element Vector{Int64}:
1
2
3
2 Likes