# Minimal example for highlighting type instability's impact on performance

**URL:** <https://discourse.julialang.org/t/minimal-example-for-highlighting-type-instabilitys-impact-on-performance/101484>\
**Category:** Teaching & Outreach\
**Created:** [July 11, 2023, 2:07pm UTC](https://discourse.julialang.org/t/minimal-example-for-highlighting-type-instabilitys-impact-on-performance/101484 "2023-07-11T14:07:11Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [July 11, 2023, 2:07pm UTC](https://discourse.julialang.org/t/minimal-example-for-highlighting-type-instabilitys-impact-on-performance/101484/1 "2023-07-11T14:07:11Z")

</div>

Hey all,

I am updating some old material from a Julia course I’ve given in the past ([Zero2Hero intensive Julia workshop - YouTube](https://www.youtube.com/watch?v=Fi7Pf2NveH0)) . Due to the huge progress of Julia release after release, I am **struggling to find a simple example that would highlight type instability and the impact it has on performance**.

I used to use this function:

```julia
@noinline function mymax(init, x)
    s = init
    for xi in x
        s = s < xi ? xi : s
    end
    return s
end

# benchmark it
using BenchmarkTools: @btime
r = rand(Int, 1000);
@btime mymax(-Inf32, $r); # 4.486 μs (0 allocations: 0 bytes)
@btime mymax(typemin(Int), $r); # 55.635 ns (0 allocations: 0 bytes)

```

however, `@code_warntype` no longer includes red text, only yellow. Additionally, I have the suspicion that the performance difference does not come from type instability, but from conversions between 32 and 64 bits. Because, this

```julia
@btime mymax(-Inf, $r); 781.731 ns (0 allocations: 0 bytes)

```

has better performance.

So, the question is, does anyone have a very simple example highlighting the problems of type isntability, that can be showcased to people just starting with Julia and only know the most basics about the Type system? Ideally something where `code_warntype` has red text?

---

<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:** [July 11, 2023, 2:16pm UTC](https://discourse.julialang.org/t/minimal-example-for-highlighting-type-instabilitys-impact-on-performance/101484/2 "2023-07-11T14:16:25Z")

</div>

```julia
julia> function mycollect(r)
           v = []
           for i in r
               push!(v, i)
           end
           v
       end
mycollect (generic function with 1 method)

julia> function mycollect2(r)
           v = eltype(r)[]
           for i in r
               push!(v, i)
           end
           v
       end
mycollect2 (generic function with 1 method)

julia> @btime mycollect(1:10_000);
  148.492 μs (9498 allocations: 474.80 KiB)

julia> @btime mycollect2(1:10_000);
  75.642 μs (9 allocations: 326.55 KiB)

```

Although, admittedly, the instability is a bit hidden here.

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [July 11, 2023, 2:19pm UTC](https://discourse.julialang.org/t/minimal-example-for-highlighting-type-instabilitys-impact-on-performance/101484/3 "2023-07-11T14:19:59Z")

</div>

But this example has much less of a performance difference between the stable and “unstable” version of the functions that are in my example code, and the `@code_warntype` macro does not display any instability. I was hoping to find a minimal example that is nevertheless truly “dramatic”.

---

<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:** [July 11, 2023, 2:32pm UTC](https://discourse.julialang.org/t/minimal-example-for-highlighting-type-instabilitys-impact-on-performance/101484/4 "2023-07-11T14:32:46Z")

</div>

Another example:

```julia
julia> rectifier(x) = x > 1 ? x : 0
rectifier (generic function with 1 method)

julia> v = Float64[-1000:1000;];

julia> @btime map(rectifier, $v);
  12.395 μs (1001 allocations: 47.23 KiB)

julia> rectifier2(x) = x > 1 ? x : zero(x)
rectifier2 (generic function with 1 method)

julia> @btime map(rectifier2, $v);
  1.315 μs (1 allocation: 15.81 KiB)

```

---

<div class="post-metadata">

**Author:** ![JonasWickman](https://avatars.discourse-cdn.com/v4/letter/j/9de0a6/32.png) [@JonasWickman](https://discourse.julialang.org/u/JonasWickman)\
**Post date:** [July 11, 2023, 2:37pm UTC](https://discourse.julialang.org/t/minimal-example-for-highlighting-type-instabilitys-impact-on-performance/101484/5 "2023-07-11T14:37:26Z")

</div>

Perhaps a little convoluted, but has a big performance impact:

```julia
F = [sin,cos]
function my_fun_1(x,F)
    F[1](x) + F[2](x)
end

function my_fun_2(x)
    sin(x) + cos(x)
end

@btime my_fun_1(1.0,$F) # 62.004 ns (5 allocations: 80 bytes)
@btime my_fun_2(1.0) # 1.080 ns (0 allocations: 0 bytes)

```

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [July 11, 2023, 2:45pm UTC](https://discourse.julialang.org/t/minimal-example-for-highlighting-type-instabilitys-impact-on-performance/101484/6 "2023-07-11T14:45:52Z")

</div>

> [@jishnub](#):
>
> ```julia
> julia> rectifier(x) = x > 1 ? x : 0
> rectifier (generic function with 1 method)
> 
> julia> v = Float64[-1000:1000;];
> 
> julia> @btime map(rectifier, $v);
> 12.395 μs (1001 allocations: 47.23 KiB)
> 
> ```

thanks, this is also very good!

> [@JonasWickman](#):
>
> ```julia
> F = [sin,cos]
> function my_fun_1(x,F)
> F[1](x) + F[2](x)
> end
> 
> ```

That’s the first example that has **red** text in the code warntype! Seems great! But also a bit tricky because a beginner will take some time to realize that in in Julia “functions are their own types”…

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [July 11, 2023, 2:49pm UTC](https://discourse.julialang.org/t/minimal-example-for-highlighting-type-instabilitys-impact-on-performance/101484/7 "2023-07-11T14:49:41Z")

</div>

I used this example in a company-internal presentation:

```julia
function f(x)
    s = 0
    for i in eachindex(x)
        s += x[i]
    end
    return s
end

```

and compared feeding it with

```julia
x1 = convert(Vector{Any}, rand(Int, 1000000));
x2 = rand(Int, 1000000);

```

This showed two orders of magnitude difference in `@btime` and instructive red lines in `@code_warntype f(x1)`.

And yes, `x1` is slightly contrived, but not unreasonable.

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [July 11, 2023, 2:51pm UTC](https://discourse.julialang.org/t/minimal-example-for-highlighting-type-instabilitys-impact-on-performance/101484/8 "2023-07-11T14:51:19Z")

</div>

Thanks. This is a good case. One way a beginner may initialize a vector of Anys that only has integers is by doing the pythonic

```julia
x = []
push!(x, number)
push!(x, number)
...

```

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [July 11, 2023, 3:04pm UTC](https://discourse.julialang.org/t/minimal-example-for-highlighting-type-instabilitys-impact-on-performance/101484/9 "2023-07-11T15:04:52Z")

</div>

Just a note, but if you have a Julia course, be sure to mention that type instability doesn’t always harm performance, it can, in fact, also be used for improving performance. If you have a demanding task it might make sense to move some of the infrequently-changing data into the type domain.

An example: say you’ve got an arithmetic expression of arbitrary structure, and you know you’ll want to evaluate it millions of times while changing some numeric values, but keeping the expression tree structure constant. It could make sense to move the tree structure into the type domain, at least partially, in such a way as to allow Julia to compile efficient code for evaluating the expression. The performance difference is basically the difference between interpretation and executing machine code, which is obviously a huge win, as long as the cost of the type instability, run-time dispatch and compilation is amortized.
