# Does specifying the element type of a Channel impact performance?

**URL:** <https://discourse.julialang.org/t/does-specifying-the-element-type-of-a-channel-impact-performance/57653>\
**Category:** General Usage\
**Tags:** question, parametric-types, channel\
**Created:** [March 21, 2021, 1:09pm UTC](https://discourse.julialang.org/t/does-specifying-the-element-type-of-a-channel-impact-performance/57653 "2021-03-21T13:09:07Z")\
**Posts on this page:** 3\
**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:** [March 21, 2021, 1:09pm UTC](https://discourse.julialang.org/t/does-specifying-the-element-type-of-a-channel-impact-performance/57653/1 "2021-03-21T13:09:07Z")

</div>

```julia
julia> a = ones(2,2);

julia> ct = Channel{Matrix{Float64}}(1)
Channel{Array{Float64,2}}(sz_max:1,sz_curr:0)

julia> @btime (put!($ct, $a); take!($ct););
  283.612 ns (0 allocations: 0 bytes)

julia> c = Channel{Any}(1);

julia> @btime (put!($c, $a); take!($c););
  286.102 ns (0 allocations: 0 bytes)

```

The performance and seems identical in either case, with no extra allocation. Is there any benefit to specifying the element type (other than dispatch)?

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [March 21, 2021, 1:15pm UTC](https://discourse.julialang.org/t/does-specifying-the-element-type-of-a-channel-impact-performance/57653/2 "2021-03-21T13:15:03Z")

</div>

> [@jishnub](#):
>
> Is there any benefit to specifying the element type

Yes, I assume you want to use the element you take from the channel, if the compiler does not know the type of the element, you’ll have type unstable code with potentially enormous consequences for performance.

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [March 21, 2021, 1:19pm UTC](https://discourse.julialang.org/t/does-specifying-the-element-type-of-a-channel-impact-performance/57653/3 "2021-03-21T13:19:04Z")

</div>

Just to elaborate on @baggepinnen’s answer, you can see the compiler isn’t able to infer the output of `take!(c)`, while it can `take!(ct)`:

```julia
julia> @code_warntype take!(c)
Variables
  #self#::Core.Const(take!)
  c::Channel{Any}

Body::Any
1 ─ %1 = Base.isbuffered(c)::Bool
└── goto #3 if not %1
2 ─ %3 = Base.take_buffered(c)::Any
└── return %3
3 ─ %5 = Base.take_unbuffered(c)::Any
└── return %5

julia> @code_warntype take!(ct)
Variables
  #self#::Core.Const(take!)
  c::Channel{Matrix{Float64}}

Body::Matrix{Float64}
1 ─ %1 = Base.isbuffered(c)::Bool
└── goto #3 if not %1
2 ─ %3 = Base.take_buffered(c)::Matrix{Float64}
└── return %3
3 ─ %5 = Base.take_unbuffered(c)::Matrix{Float64}
└── return %5

```

And the benchmark does slow down for `c` relative to `ct` if you do something with the result, e.g. adding a `sum`:

```julia
julia> @benchmark (put!($ct, $a); rt=take!($ct); sum(rt))
BenchmarkTools.Trial:
  memory estimate: 0 bytes
  allocs estimate: 0
  --------------
  minimum time: 208.182 ns (0.00% GC)
  median time: 211.186 ns (0.00% GC)
  mean time: 213.535 ns (0.00% GC)
  maximum time: 381.306 ns (0.00% GC)
  --------------
  samples: 10000
  evals/sample: 555

julia> @benchmark (put!($c, $a); r=take!($c); sum(r))
BenchmarkTools.Trial:
  memory estimate: 16 bytes
  allocs estimate: 1
  --------------
  minimum time: 232.654 ns (0.00% GC)
  median time: 237.932 ns (0.00% GC)
  mean time: 243.619 ns (0.14% GC)
  maximum time: 3.551 μs (93.20% GC)
  --------------
  samples: 10000
  evals/sample: 442

```

(though not by that much in this example, except when garbage collection runs).
