# Efficient popnfirst!?

**URL:** https://discourse.julialang.org/t/efficient-popnfirst/57190
**Category:** Performance
**Created:** [March 15, 2021, 11:59am UTC](https://discourse.julialang.org/t/efficient-popnfirst/57190 "2021-03-15T11:59:16Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![HenriDeh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrideh/32/8316_2.png) [@HenriDeh](https://discourse.julialang.org/u/HenriDeh)
#### Post date: [March 15, 2021, 11:59am UTC](https://discourse.julialang.org/t/efficient-popnfirst/57190/1 "2021-03-15T11:59:16Z")

</div>

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 ?

---

<div class="post-metadata">

### Author: ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)
#### Post date: [March 15, 2021, 12:05pm UTC](https://discourse.julialang.org/t/efficient-popnfirst/57190/2 "2021-03-15T12:05:27Z")

</div>

What problem do you have with: `[popfirst!(xs) for _ in 1:n]` ?

---

<div class="post-metadata">

### Author: ![mike](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike/32/39_2.png) [@mike](https://discourse.julialang.org/u/mike)
#### Post date: [March 15, 2021, 12:06pm UTC](https://discourse.julialang.org/t/efficient-popnfirst/57190/3 "2021-03-15T12:06:51Z")

</div>

`deleteat!(a, 1:n)` _might_ be efficient, I’ve not looked at the implementation, but I’d assume it’s slightly better.

---

<div class="post-metadata">

### Author: ![HenriDeh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrideh/32/8316_2.png) [@HenriDeh](https://discourse.julialang.org/u/HenriDeh)
#### Post date: [March 15, 2021, 12:07pm UTC](https://discourse.julialang.org/t/efficient-popnfirst/57190/4 "2021-03-15T12:07:11Z")

</div>

It’s just that I don’t know if it’s efficient to do multiple calls like that instead of removing one by one.

---

<div class="post-metadata">

### Author: ![HenriDeh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrideh/32/8316_2.png) [@HenriDeh](https://discourse.julialang.org/u/HenriDeh)
#### Post date: [March 15, 2021, 12:08pm UTC](https://discourse.julialang.org/t/efficient-popnfirst/57190/5 "2021-03-15T12:08:32Z")

</div>

Okay thanks, it will do the trick for what I need. I didn’t know deleteat accepts ranges.

---

<div class="post-metadata">

### Author: ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)
#### Post date: [March 15, 2021, 12:10pm UTC](https://discourse.julialang.org/t/efficient-popnfirst/57190/6 "2021-03-15T12:10:16Z")

</div>

> 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
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)

```

---

<div class="post-metadata">

### Author: ![mike](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike/32/39_2.png) [@mike](https://discourse.julialang.org/u/mike)
#### Post date: [March 15, 2021, 12:14pm UTC](https://discourse.julialang.org/t/efficient-popnfirst/57190/7 "2021-03-15T12:14:06Z")

</div>

Probably the lack of allocation since it’s not creating the comprehension?

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [March 15, 2021, 12:14pm UTC](https://discourse.julialang.org/t/efficient-popnfirst/57190/8 "2021-03-15T12:14:52Z")

</div>

> [@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).

---

<div class="post-metadata">

### Author: ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)
#### Post date: [March 15, 2021, 12:16pm UTC](https://discourse.julialang.org/t/efficient-popnfirst/57190/9 "2021-03-15T12:16:05Z")

</div>

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`).

---

<div class="post-metadata">

### Author: ![HenriDeh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrideh/32/8316_2.png) [@HenriDeh](https://discourse.julialang.org/u/HenriDeh)
#### Post date: [March 15, 2021, 12:18pm UTC](https://discourse.julialang.org/t/efficient-popnfirst/57190/10 "2021-03-15T12:18:32Z")

</div>

Well, not in my case but it’s true that it could be.

---

<div class="post-metadata">

### Author: ![mike](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike/32/39_2.png) [@mike](https://discourse.julialang.org/u/mike)
#### Post date: [March 15, 2021, 12:20pm UTC](https://discourse.julialang.org/t/efficient-popnfirst/57190/11 "2021-03-15T12:20:39Z")

</div>

Yeah, true, probably saving `x[1:n]` prior to `deleteat!` would be a better option then, maybe:

```julia
julia> function popnfirst!(xs, n)
           out = xs[1:n]
           deleteat!(xs, 1:n)
           return out
       end

```

---

<div class="post-metadata">

### Author: ![HenriDeh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrideh/32/8316_2.png) [@HenriDeh](https://discourse.julialang.org/u/HenriDeh)
#### Post date: [March 15, 2021, 12:24pm UTC](https://discourse.julialang.org/t/efficient-popnfirst/57190/12 "2021-03-15T12:24:07Z")

</div>

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.

---

<div class="post-metadata">

### Author: ![mike](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike/32/39_2.png) [@mike](https://discourse.julialang.org/u/mike)
#### Post date: [March 15, 2021, 12:29pm UTC](https://discourse.julialang.org/t/efficient-popnfirst/57190/13 "2021-03-15T12:29:38Z")

</div>

`splice!` may be what you want actually…

```julia
julia> splice!([1, 2, 3, 4, 5], 1:3)
3-element Vector{Int64}:
 1
 2
 3

```
