# Performance issue with use of eltype()?

**URL:** <https://discourse.julialang.org/t/performance-issue-with-use-of-eltype/5764>\
**Category:** General Usage\
**Tags:** performance\
**Created:** [September 7, 2017, 6:07pm UTC](https://discourse.julialang.org/t/performance-issue-with-use-of-eltype/5764 "2017-09-07T18:07:54Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [September 7, 2017, 6:07pm UTC](https://discourse.julialang.org/t/performance-issue-with-use-of-eltype/5764/1 "2017-09-07T18:07:54Z")

</div>

I am at a loss to explain the performance difference between these two functions. Can someone help?

```julia
julia> function foo(a::AbstractVector)
           T = eltype(a)
           c = Set{T}[Set{T}() for x in a]
           return length(c)
       end
foo (generic function with 1 method)

julia> function bar(a::Vector{T}) where T
         c = Set{T}[Set{T}() for x in a]
         return length(c)
       end
bar (generic function with 1 method)

julia> a = rand(1:100_000, 2_000_000);

julia> eltype(a)
Int64

julia> @benchmark foo($a)
BenchmarkTools.Trial:
  memory estimate: 961.30 MiB
  allocs estimate: 10000004
  --------------
  minimum time: 3.654 s (14.18% GC)
  median time: 3.797 s (17.07% GC)
  mean time: 3.797 s (17.07% GC)
  maximum time: 3.939 s (19.76% GC)
  --------------
  samples: 2
  evals/sample: 1

julia> @benchmark bar($a)
BenchmarkTools.Trial:
  memory estimate: 961.30 MiB
  allocs estimate: 10000003
  --------------
  minimum time: 283.377 ms (0.00% GC)
  median time: 983.086 ms (65.25% GC)
  mean time: 1.080 s (68.63% GC)
  maximum time: 2.720 s (87.05% GC)
  --------------
  samples: 6
  evals/sample: 1

julia> foo(a) == bar(a)
true

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [September 7, 2017, 6:17pm UTC](https://discourse.julialang.org/t/performance-issue-with-use-of-eltype/5764/2 "2017-09-07T18:17:45Z")

</div>

Please don’t cross post or at least link to the other places you post to.

It’s unrelated to `eltype` but closure capture variable. See my comment in [https://github.com/JuliaLang/julia/issues/23618](https://github.com/JuliaLang/julia/issues/23618)

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [September 7, 2017, 6:18pm UTC](https://discourse.julialang.org/t/performance-issue-with-use-of-eltype/5764/3 "2017-09-07T18:18:43Z")

</div>

@yuyichao this is a separate issue. Notice that the generator is explicit with `Set{T}[...]` in both functions, unlike the github issue I posted.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [September 7, 2017, 6:19pm UTC](https://discourse.julialang.org/t/performance-issue-with-use-of-eltype/5764/4 "2017-09-07T18:19:59Z")

</div>

Didn’t notice that although it’s actually still the same issue. The explicitly specified type hides the type instability on the final value but not in the loop.

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [September 7, 2017, 6:20pm UTC](https://discourse.julialang.org/t/performance-issue-with-use-of-eltype/5764/5 "2017-09-07T18:20:24Z")

</div>

Neither `foo` nor `bar` is warning of any type instability.

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [September 7, 2017, 6:21pm UTC](https://discourse.julialang.org/t/performance-issue-with-use-of-eltype/5764/6 "2017-09-07T18:21:42Z")

</div>

This is fast for any abstract array, in case that is an issue:

```julia
function foobar(a::AV) where AV<:AbstractVector{T} where T
                c = Set{T}[Set{T}() for x in a]
                return length(c)
end

```

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [September 7, 2017, 6:28pm UTC](https://discourse.julialang.org/t/performance-issue-with-use-of-eltype/5764/7 "2017-09-07T18:28:04Z")

</div>

> [@anon94023334](#):
>
> Neither foo nor bar is warning of any type instability.

The type instability is hiden in the (not inlined in this case) implementation of comprehension.

If you want to see it, you’ll need to look into the line that implements comprehention

```julia
      c::Array{Set{Int64},1} = $(Expr(:invoke, MethodInstance for copy!(::Array{Set{Int64},1}, ::Base.Generator{Array{Int64,1},getfield(Main, Symbol("##1#2")){DataType}}), :(Base.copy!), :($(Expr(:foreigncall, :(:jl_alloc_array_1d), Array{Set{Int64},1}, svec(Any, Int64), :(:ccall), 2, Array{Set{Int64},1}, :((Base.select_value)((Base.slt_int)(SSAValue(4), 0)::Bool, 0, SSAValue(4))::Int64)))), SSAValue(2)))::Array{Set{Int64},1}

```

And show the `code_warntype` of that. You can get a hint about it from `::Base.Generator{Array{Int64,1},getfield(Main, Symbol("##1#2")){DataType}}` showing that the closure is only parametrized for `{DataType}` and not `{Type{Int64}}`.

---

<div class="post-metadata">

**Author:** ![anon94023334](https://avatars.discourse-cdn.com/v4/letter/a/e274bd/32.png) [@anon94023334](https://discourse.julialang.org/u/anon94023334)\
**Post date:** [September 7, 2017, 6:28pm UTC](https://discourse.julialang.org/t/performance-issue-with-use-of-eltype/5764/8 "2017-09-07T18:28:57Z")

</div>

Ah, cool. I understand. Thanks.
