# How to work with \`Base.Generator\` efficiently

**URL:** https://discourse.julialang.org/t/how-to-work-with-base-generator-efficiently/248
**Category:** General Usage
**Created:** [November 11, 2016, 9:55am UTC](https://discourse.julialang.org/t/how-to-work-with-base-generator-efficiently/248 "2016-11-11T09:55:29Z")
**Posts on this page:** 7
**Page:** 1

<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: [November 11, 2016, 9:55am UTC](https://discourse.julialang.org/t/how-to-work-with-base-generator-efficiently/248/1 "2016-11-11T09:55:29Z")

</div>

I was calculating some statistics on an irregular data stored in a `Dict`, when I learned that `StatsBase.countmap` does not support generators. Since it is time I learned how to use them, I thought I would implement a method:

```julia
using StatsBase

function StatsBase.addcounts!{T}(cm::Dict{T}, g::Base.Generator)
    ## how to make sure T matches eltype of g?
    for v in g
        cm[v] = get(cm, v, 0) + 1
    end
    cm
end

function StatsBase.countmap(g::Base.Generator)
    _eltype = Base.iteratoreltype(g)
    if _eltype == Base.EltypeUnknown()
        _eltype = Any
    end
    addcounts!(Dict{_eltype, Int}(), g)
end

```

But it is about 3x slower than just collecting the values (note: `records` and the calculation I do on them is just a toy example, to make my code self-contained):

```julia
records = Dict(rand(Int) => rand(Int, rand(1:5)) for i in 1:200000)
using BenchmarkTools
@benchmark countmap(collect(length(v) for v in values(records)))
@benchmark countmap(length(v) for v in values(records))

```

I suspect my code is not type stable: it does not use the element type of the generator, for one thing. So how can I speed this up? Apologies if this is in the manual, I could not find it.

---

<div class="post-metadata">

### Author: ![Ward9250](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ward9250/32/42768_2.png) [@Ward9250](https://discourse.julialang.org/u/Ward9250)
#### Post date: [November 11, 2016, 11:09am UTC](https://discourse.julialang.org/t/how-to-work-with-base-generator-efficiently/248/2 "2016-11-11T11:09:54Z")

</div>

If you suspect the code is not type-stable, have you tried `@code_warntype` to try and see this?

---

<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: [November 11, 2016, 11:28am UTC](https://discourse.julialang.org/t/how-to-work-with-base-generator-efficiently/248/3 "2016-11-11T11:28:29Z")

</div>

I did. I just don’t know how to fix it. I imagine that somehow I would need to dispatch on the eltype of the iterator, but I am not even sure about this.

---

<div class="post-metadata">

### Author: ![nalimilan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nalimilan/32/147_2.png) [@nalimilan](https://discourse.julialang.org/u/nalimilan)
#### Post date: [November 11, 2016, 1:50pm UTC](https://discourse.julialang.org/t/how-to-work-with-base-generator-efficiently/248/4 "2016-11-11T13:50:35Z")

</div>

`Base.iteratoreltype` always returns `EltypeUnknown()` for generators. Not sure why.

EDIT: looks like the required code is just missing at the moment, see this thread: [https://groups.google.com/d/msg/julia-users/G-olgn3mIks/42WJAyDPBAAJ](https://groups.google.com/d/msg/julia-users/G-olgn3mIks/42WJAyDPBAAJ)

---

<div class="post-metadata">

### Author: ![carlobaldassi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carlobaldassi/32/37_2.png) [@carlobaldassi](https://discourse.julialang.org/u/carlobaldassi)
#### Post date: [November 11, 2016, 4:41pm UTC](https://discourse.julialang.org/t/how-to-work-with-base-generator-efficiently/248/5 "2016-11-11T16:41:37Z")

</div>

One trick that is used in Base is to pass the result of `start` to an auxiliary function, see e.g. [here](https://github.com/JuliaLang/julia/blob/ce6a0c30564f8022bfde0b4696e32230cede5941/base/bitarray.jl#L632-L654) (I copied that trick from some other part of Base but I don’t remember where). Hope this helps.

---

<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: [November 12, 2016, 8:57am UTC](https://discourse.julialang.org/t/how-to-work-with-base-generator-efficiently/248/6 "2016-11-12T08:57:59Z")

</div>

@carlobaldassi: Maybe I am not getting it, but how can I (or the compiler) be sure that the type of `start(itr)` is the same as the type for all elements?

@nalimilan: Do you know if anyone opened an issue in the end?

---

<div class="post-metadata">

### Author: ![cortner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cortner/32/204_2.png) [@cortner](https://discourse.julialang.org/u/cortner)
#### Post date: [November 14, 2016, 7:42pm UTC](https://discourse.julialang.org/t/how-to-work-with-base-generator-efficiently/248/7 "2016-11-14T19:42:55Z")

</div>

I think this issue has been resolved in master and in 0.5.1. [18695](https://github.com/JuliaLang/julia/issues/18695)
