# Why is iterating over an Iterators.drop slower than iterating over the parent?

**URL:** <https://discourse.julialang.org/t/why-is-iterating-over-an-iterators-drop-slower-than-iterating-over-the-parent/54315>\
**Category:** General Usage\
**Tags:** question, iterators\
**Created:** [January 31, 2021, 7:53am UTC](https://discourse.julialang.org/t/why-is-iterating-over-an-iterators-drop-slower-than-iterating-over-the-parent/54315 "2021-01-31T07:53:29Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [January 31, 2021, 7:53am UTC](https://discourse.julialang.org/t/why-is-iterating-over-an-iterators-drop-slower-than-iterating-over-the-parent/54315/1 "2021-01-31T07:53:29Z")

</div>

Two ways to compute the last element of an iterator `itr` are:

1. `foldl((_, y) -> y, itr)`
2. `first(Iterators.drop(itr, length(itr) - 1))`

however, the second seems much slower than the first. I wonder why this is the case?

For example:

```julia
julia> itr = Iterators.product(1:3000, 2:3000);

julia> @btime foldl((_, y) -> y, $itr)
  6.440 ms (0 allocations: 0 bytes)
(3000, 3000)

julia> @btime first(Iterators.drop($it, length($it) - 1))
  9.534 ms (0 allocations: 0 bytes)
(3000, 3000)

```

Iterating over an `Iterators.Drop` effectively relies on iterating over the parent, so I am not sure why there’s this difference?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 31, 2021, 1:14pm UTC](https://discourse.julialang.org/t/why-is-iterating-over-an-iterators-drop-slower-than-iterating-over-the-parent/54315/2 "2021-01-31T13:14:55Z")

</div>

I can replicate this, but don’t have an explanation. Note that for some other iterables (eg `UnitRange`), the timings are reversed.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [January 31, 2021, 3:54pm UTC](https://discourse.julialang.org/t/why-is-iterating-over-an-iterators-drop-slower-than-iterating-over-the-parent/54315/3 "2021-01-31T15:54:18Z")

</div>

Just in case, @stevengj’ s solution posted [here](https://discourse.julialang.org/t/getting-the-last-element-of-an-iterator/49696/15) for computing the last element of an iterator is lightning-fast:

```julia
julia> @btime first(Iterators.reverse($itr))
  6.600 ns (0 allocations: 0 bytes)
(3000, 3000)

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [February 2, 2021, 4:31pm UTC](https://discourse.julialang.org/t/why-is-iterating-over-an-iterators-drop-slower-than-iterating-over-the-parent/54315/4 "2021-02-02T16:31:21Z")

</div>

This is applicable for iterators that implemented reverse, otherwise it is not faster than traversing the iterator.
