# Should broadcasting be avoided for type unstable code?

**URL:** https://discourse.julialang.org/t/should-broadcasting-be-avoided-for-type-unstable-code/79438
**Category:** Performance
**Created:** [April 13, 2022, 3:14pm UTC](https://discourse.julialang.org/t/should-broadcasting-be-avoided-for-type-unstable-code/79438 "2022-04-13T15:14:18Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)
#### Post date: [April 13, 2022, 3:14pm UTC](https://discourse.julialang.org/t/should-broadcasting-be-avoided-for-type-unstable-code/79438/1 "2022-04-13T15:14:18Z")

</div>

This simple expression incurs an overhead of 0.13 seconds in a fresh REPL (Julia 1.7.1).

```julia
julia> @time (x -> x .+ 1)(Any[2])
  0.128635 seconds (458.42 k allocations: 25.632 MiB, 11.29% gc time, 99.23% compilation time)
1-element Vector{Int64}:
 3

```

I’m surprised that such short code can need so much time to compile, I imagine how many of these come together in normal code bases. Our problem in Makie is that we often have to deal with type instabilities, so I’m wondering if we should generally avoid broadcasting around such code, and what other anti-patterns might be.

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [April 13, 2022, 3:23pm UTC](https://discourse.julialang.org/t/should-broadcasting-be-avoided-for-type-unstable-code/79438/2 "2022-04-13T15:23:42Z")

</div>

Are you sure the broadcasting is the problem there?

```julia
julia> @time (x -> x .+ 1)(Any[2])
  0.094409 seconds (427.71 k allocations: 24.001 MiB, 14.06% gc time, 95.70% compilation time)
1-element Vector{Int64}:
 3

julia> function g(x)
           h = x -> x .+ 1
           return h(x)
       end
g (generic function with 1 method)

julia> @time g(Any[2])
  0.000027 seconds (10 allocations: 464 bytes)
1-element Vector{Int64}:
 3

julia> f(x) = x .+ 1
f (generic function with 1 method)

julia> @time f(Any[2])
  0.000021 seconds (10 allocations: 464 bytes)
1-element Vector{Int64}:
 3

```

Seems more related to fact that the function itself is a type-unstable object:

```julia
julia> f = x -> x .+ 1
#1 (generic function with 1 method)

julia> @time f(Any[2])
  0.075440 seconds (426.73 k allocations: 23.939 MiB, 16.28% gc time, 99.89% compilation time)
1-element Vector{Int64}:
 3

```

---

<div class="post-metadata">

### Author: ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)
#### Post date: [April 13, 2022, 3:48pm UTC](https://discourse.julialang.org/t/should-broadcasting-be-avoided-for-type-unstable-code/79438/3 "2022-04-13T15:48:01Z")

</div>

I think you can only test the latency once per session, after that some broadcasting machinery will be compiled

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [April 13, 2022, 3:55pm UTC](https://discourse.julialang.org/t/should-broadcasting-be-avoided-for-type-unstable-code/79438/4 "2022-04-13T15:55:35Z")

</div>

True, still the other options are faster:

```julia
julia> f(x) = x .+ 1
f (generic function with 1 method)

julia> @time f(Any[2])
  0.015672 seconds (33.22 k allocations: 1.776 MiB, 99.64% compilation time)
1-element Vector{Int64}:
 3

```

Actually here:

```julia
julia> @time let
           f(x) = x .+ 1
           f(Any[2])
       end
  0.097507 seconds (427.71 k allocations: 24.001 MiB, 13.89% gc time, 96.22% compilation time)
1-element Vector{Int64}:
 3

```

I get the same result as yours. Is some compilation of the machinery occurring when the function is initially defined (in the previous example). That surprises me.
