# Blog post: How to optimise Julia code: A practical guide

**URL:** <https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473>\
**Category:** Community\
**Created:** [June 9, 2022, 7:34am UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473 "2022-06-09T07:34:23Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)\
**Post date:** [June 9, 2022, 7:34am UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473/1 "2022-06-09T07:34:23Z")

</div>

Hello all!

I made a new blog post on how to optimise Julia code. Any comments are welcome!

[https://viralinstruction.com/posts/optimise/](https://viralinstruction.com/posts/optimise/)

---

<div class="post-metadata">

**Author:** ![maxkapur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxkapur/32/21208_2.png) [@maxkapur](https://discourse.julialang.org/u/maxkapur)\
**Post date:** [June 9, 2022, 12:15pm UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473/2 "2022-06-09T12:15:12Z")

</div>

Thank you for this interesting and informative post. FYI, there is a very small typo in the data locality section, where you define the struct

```julia
struct FooArray
 as::Vector{Int32}
 bs::Vector{Int16}
end

```

In context, it should be `bs::Vector{UInt16}`.

I have a question about data locality principles but I will make a separate thread and @ you rather than clutter up this one.

---

<div class="post-metadata">

**Author:** ![patrick](https://avatars.discourse-cdn.com/v4/letter/p/b2d939/32.png) [@patrick](https://discourse.julialang.org/u/patrick)\
**Post date:** [June 9, 2022, 4:43pm UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473/3 "2022-06-09T16:43:46Z")

</div>

This is fantastic! Thank you for writing it.

---

<div class="post-metadata">

**Author:** ![haberdashPI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/haberdashpi/32/26337_2.png) [@haberdashPI](https://discourse.julialang.org/u/haberdashPI)\
**Post date:** [June 9, 2022, 5:12pm UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473/4 "2022-06-09T17:12:18Z")

</div>

Great to see this topic getting some love. Thanks for your time and energy.

I’m surprised you recommend reviewing algorithms as 3rd on your list. It can easily contain the lowest hanging fruit. If you can easily go from O(N^3) to O(N log N) with a change to one top-level function, making your code type stable might be unnecessary. Of course, YMMV.

---

<div class="post-metadata">

**Author:** ![fortunewalla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fortunewalla/32/36960_2.png) [@fortunewalla](https://discourse.julialang.org/u/fortunewalla)\
**Post date:** [June 10, 2022, 2:27am UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473/5 "2022-06-10T02:27:24Z")

</div>

I am wondering if you would consider making a copy of your article over to [forem.julialang.org](http://forem.julialang.org). That is an official Julia forum is meant for Julia specific long form content such as this and has built-in SEO for original links and would give it more traction and not to mention be of great benefit to the community. Thanks

---

<div class="post-metadata">

**Author:** ![maxkapur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxkapur/32/21208_2.png) [@maxkapur](https://discourse.julialang.org/u/maxkapur)\
**Post date:** [June 10, 2022, 3:33am UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473/6 "2022-06-10T03:33:16Z")

</div>

I wonder if this editorial choice can be explained by the desire to avoid scope creep. Improving your algorithm is a great way to optimize code in _any language,_ but the subject at hand is how to optimize _Julia code._ For people like me who have a high-level understanding of algorithms and computational complexity but are just bad at coding, this kind of tutorial is a wonderful resource.

---

<div class="post-metadata">

**Author:** ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)\
**Post date:** [June 10, 2022, 8:01pm UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473/7 "2022-06-10T20:01:35Z")

</div>

The reason choosing the right algorithms is number 3 is that the first two are more important.

The first one is type stability. I consider this as much an aspect of code quality as about performance. If possible, one should type stabilize your code. And if one isn’t sure if the code is as type stable as it ought to be, one has no business optimising the code.

The second one is profiling. It doesn’t matter if some part of your code is O(n^3), if your function call spends 0.01% runtime there. Making it O(n log(n)) or whatever will make no practical difference, only potentially cause issues. Only optimise what matters.

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [June 10, 2022, 11:48pm UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473/8 "2022-06-10T23:48:09Z")

</div>

> A good place to start is to look for vectorisation. If you believe the code _should_ vectorise, scan the assembly for the presence of vector instructions, which can be identified in x86 assembly by usually beginning with “`vp`”.

You only do integer operations?

Also, Cthulhu.jl is excellent. It is much better than `@code_warntype`, `@code_typed`, `@code_native`, and `@code_llvm`. You are grossly mischaracterizing it IMO.

---

<div class="post-metadata">

**Author:** ![haberdashPI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/haberdashpi/32/26337_2.png) [@haberdashPI](https://discourse.julialang.org/u/haberdashPI)\
**Post date:** [June 11, 2022, 12:53am UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473/9 "2022-06-11T00:53:24Z")

</div>

> [@jakobnissen](#):
>
> And if one isn’t sure if the code is as type stable as it ought to be, one has no business optimising the code.

Though I believe I agree with the spirit of your point, I think this goes a bit far.

Ways I agree:

1.) I’m open to the possibility that for a new comer to Julia, the emphasis should be more on type stability

2.) There are absolutely cases where it makes more sense to start with type stability, but I think that should be judged on a case-by-case basis.

Rather than having a fixed order, I’d argue one should be looking for the lowest hanging fruit and track the effects of said changes empirically. If it would take 5-mintues to switch algorithms, and 60-minutes to improve type stability, why not try the 5-minute fix and see if it helps enough that you don’t have to bother optimizing further? 🤷

> It doesn’t matter if some part of your code is O(n^3), if your function call spends 0.01% runtime there.

Agreed, but sometimes formal profiling of the code would take longer than just switching algorithms and seeing if it helps or not.

---

<div class="post-metadata">

**Author:** ![brenhinkeller](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brenhinkeller/32/36648_2.png) [@brenhinkeller](https://discourse.julialang.org/u/brenhinkeller)\
**Post date:** [June 11, 2022, 2:07am UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473/10 "2022-06-11T02:07:53Z")

</div>

Great post!

As an anecdote, I will say that understanding type stability (and consequences of multiple dispatch more generally) was for me _the_ key thing I was missing to make all the pieces fall into place when I was new to the language, and the main difference maker between loving the language and leaving in frustration. At this point it’s in the first week of my “intro to computation for Earth sciences” course I think. So happy to see it emphasized here!

I’ll also echo Chris that Cthulhu.jl is actually not nearly as scary as the name might suggest – I only started using it in the past month or so, but I now default to it pretty much every time over @code\_warntype / @code\_typed / @code\_llvm / @code\_native

---

<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:** [June 11, 2022, 6:47am UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473/11 "2022-06-11T06:47:49Z")

</div>

When debugging performance issues in Makie I often have the problem that there are many type instabilities but those can neither be removed nor do they have to matter for performance. But they do make using tools like JET or Cthulhu harder because at every dynamic dispatch they give up. I’d actually need a dynamic debugger in conjunction with these tools, but so far the debuggers we have were either much too slow or crashed or were difficult to understand / erratic in the way they jumped around places in the code when stepping.

---

<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:** [June 11, 2022, 8:57am UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473/12 "2022-06-11T08:57:40Z")

</div>

> [@haberdashPI](#):
>
> sometimes formal profiling of the code would take longer than just switching algorithms and seeing if it helps

I am not sure about this — with tooling like

> **[GitHub - timholy/ProfileView.jl: Visualization of Julia profiling data](https://github.com/timholy/ProfileView.jl)**
>
> Visualization of Julia profiling data. Contribute to timholy/ProfileView.jl development by creating an account on GitHub.

I find profiling very convenient.

In any case, I agree both with you and @jakobnissen to some extent: algorithmic improvements are great if you can obtain them, but that’s not always possible and sometimes requires a bit if creativity. And, of course, it is difficult to write a concise _general_ guide about doing this.

OTOH, fixing up type stability problems and profiling is a reasonably mechanical process that is worth learning about.

A small comment about the post: I find the built in memory-allocation profiling impractical in Julia, and always end up resorting to allocation analysis with

> **[GitHub - KristofferC/TimerOutputs.jl: Formatted output of timed sections in...](https://github.com/KristofferC/TimerOutputs.jl)**
>
> Formatted output of timed sections in Julia. Contribute to KristofferC/TimerOutputs.jl development by creating an account on GitHub.

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [June 11, 2022, 2:36pm UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473/13 "2022-06-11T14:36:02Z")

</div>

> [@Tamas\_Papp](#):
>
> A small comment about the post: I find the built in memory-allocation profiling impractical in Julia, and always end up resorting to allocation analysis with

Dito, but I haven’t tried the new memory profiler yet. Have you?

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [June 11, 2022, 4:56pm UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473/14 "2022-06-11T16:56:39Z")

</div>

What’s the new profiler?

---

<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:** [June 11, 2022, 5:41pm UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473/15 "2022-06-11T17:41:21Z")

</div>

[https://docs.julialang.org/en/v1.9-dev/manual/profile/#Allocation-Profiler](https://docs.julialang.org/en/v1.9-dev/manual/profile/#Allocation-Profiler)

It’s in Julia 1.8

---

<div class="post-metadata">

**Author:** ![brenhinkeller](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brenhinkeller/32/36648_2.png) [@brenhinkeller](https://discourse.julialang.org/u/brenhinkeller)\
**Post date:** [June 11, 2022, 5:42pm UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473/16 "2022-06-11T17:42:38Z")

</div>

TIL, awesome! Sounds like a big upgrade over the old version that wrote a zillion files you had to find and read and clean up.

---

<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:** [June 11, 2022, 5:46pm UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473/17 "2022-06-11T17:46:43Z")

</div>

My understanding is it was an awesome contribution by RelationalAI: [https://github.com/JuliaLang/julia/pull/42768](https://github.com/JuliaLang/julia/pull/42768). They’ve also got other really interesting PRs like [https://github.com/JuliaLang/julia/pull/42286](https://github.com/JuliaLang/julia/pull/42286).

---

<div class="post-metadata">

**Author:** ![brenhinkeller](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brenhinkeller/32/36648_2.png) [@brenhinkeller](https://discourse.julialang.org/u/brenhinkeller)\
**Post date:** [June 11, 2022, 6:05pm UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473/18 "2022-06-11T18:05:32Z")

</div>

Woah, awesome! Hope that gets merged soon too!

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [June 11, 2022, 6:48pm UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473/19 "2022-06-11T18:48:46Z")

</div>

May I ask why in the `Use multiple threads` section of the blog post, the package `Folds.jl` and the broader `JuliaFolds` ecosystem are recommended, but not also the popular `LoopVectorization.jl` package and the `JuliaSIMD `organization? Thank you, from a newbie.

---

<div class="post-metadata">

**Author:** ![brenhinkeller](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brenhinkeller/32/36648_2.png) [@brenhinkeller](https://discourse.julialang.org/u/brenhinkeller)\
**Post date:** [June 11, 2022, 8:05pm UTC](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473/20 "2022-06-11T20:05:33Z")

</div>

Huh, I hadn’t noticed that at first. I can certainly recommend LoopVectorization.jl from my own experience! I guess at first LoopVectorization was only singlthreaded, but `@tturbo` (which multithreads via Polyester.jl) is IMHO one of the easiest ways to get really performant multithreading on (reorderable) loops.

[Next page](https://discourse.julialang.org/t/blog-post-how-to-optimise-julia-code-a-practical-guide/82473.md?page=2)
