# How to optimize the following code?

**URL:** <https://discourse.julialang.org/t/how-to-optimize-the-following-code/33209>\
**Category:** Performance\
**Created:** [January 10, 2020, 7:08pm UTC](https://discourse.julialang.org/t/how-to-optimize-the-following-code/33209 "2020-01-10T19:08:10Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Iulian.Cioarca](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iulian.cioarca/32/30166_2.png) [@Iulian.Cioarca](https://discourse.julialang.org/u/Iulian.Cioarca)\
**Post date:** [January 10, 2020, 7:08pm UTC](https://discourse.julialang.org/t/how-to-optimize-the-following-code/33209/1 "2020-01-10T19:08:10Z")

</div>

I recently watched this video which ended in a comparison between Python+Numba vs Julia (starting around 1h:06m):

[![](https://global.discourse-cdn.com/julialang/original/3X/1/8/181bf107053ef702b8c76d3915fcae5007f01860.jpeg "How to learn Julia, a new programming language") ](https://www.youtube.com/watch?v=TNoShNPoEak)

The author used multithreading to run the same function 10\_000 times and concluded that Julia was slower than Numba.

I was wondering if the code could be optimized. Some of the lines could be deleted altogether, but for the sake of comparison with Numba, I kept them.

```julia
# mass spring damper

function friction(v::Float64, vt::Float64)
    v > vt ? -3v : -3vt*sign(v)
    end
end

function simulate(x0::Float64; T = 10.0, dt = 0.0001, vt = 1.0)
    times = 0.0:dt:T
    positions = zeros(length(times))
    v = 0.0
    a = 0.0
    x = x0
    positions[1] = x0/x0
    for ii in 1:length(times)
        if ii == 0
            continue
        end
        t = times[ii]
        a = friction(v, vt) - 100.0*x
        v = v + a * dt
        x = x + v * dt
        positions[ii] = x/x0
    end
    (times, positions)
end

@time simulate(10.0);
using Plots
plot(simulate(10.0)...)

function rep(z)
    Threads.@threads for i = 1:z
        x = simulate(10.0);
    end
end

@time rep(1)
@time rep(10_000)

```

---

<div class="post-metadata">

**Author:** ![AndiMD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andimd/32/6531_2.png) [@AndiMD](https://discourse.julialang.org/u/AndiMD)\
**Post date:** [January 10, 2020, 10:57pm UTC](https://discourse.julialang.org/t/how-to-optimize-the-following-code/33209/2 "2020-01-10T22:57:59Z")

</div>

Nice video. This gives a good perspective on beginner’s issues.

You already did the obvious thing: Replacing `[0.0:dt:T;]` with the range `0.0:dt:T` makes the timing go down from 3.1s to 2.2s on my machine.

The function itself looks good to me (although it does some useless work). Make sure you start julia with highest performance optimizations -O3. Numba is pretty good, it will be hard to beat that.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [January 10, 2020, 11:04pm UTC](https://discourse.julialang.org/t/how-to-optimize-the-following-code/33209/3 "2020-01-10T23:04:46Z")

</div>

Turn off bounds checking with `@inbounds` and throw `@inline` on the friction term? Probably calculate the friction with `ifelse`.

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [January 10, 2020, 11:13pm UTC](https://discourse.julialang.org/t/how-to-optimize-the-following-code/33209/4 "2020-01-10T23:13:54Z")

</div>

@ChrisRackauckas shouldn’t `friction be short enough for automatic inlining?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [January 10, 2020, 11:18pm UTC](https://discourse.julialang.org/t/how-to-optimize-the-following-code/33209/5 "2020-01-10T23:18:44Z")

</div>

It should be. Should.

---

<div class="post-metadata">

**Author:** ![Amin\_Yahyaabadi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amin_yahyaabadi/32/9826_2.png) [@Amin\_Yahyaabadi](https://discourse.julialang.org/u/Amin_Yahyaabadi)\
**Post date:** [January 10, 2020, 11:35pm UTC](https://discourse.julialang.org/t/how-to-optimize-the-following-code/33209/6 "2020-01-10T23:35:14Z")

</div>

- Replacing `[0.0:dt:T;]` with the range `0.0:dt:T` reduces time by ~30%

- Using `@fastmath` reduces time by ~30%

- The way you benchmark the code is not reliable. Use BenchmarkTools.

- Using `@inbounds` may have an effect too. Not much visible by these parameters.

- Micro optimizations are possible by removing unused sentences and `if` check

```julia
using BenchmarkTools
@btime simulate_optimized(10.0);
  577.200 μs (3 allocations: 781.45 KiB)

@btime simulate(10.0);
  1.086 ms (5 allocations: 1.53 MiB)

```

The function:

```julia
function simulate_optimized(x0::Float64; T = 10.0, dt = 0.0001, vt = 1.0)
    times = 0.0:dt:T
    positions = zeros(length(times))
    v = 0.0
    a = 0.0
    x = x0
    positions[1] = 1.0 #x0/x0
    for ii in 1:length(times)

        ## not needed!
        # if ii === 0
        # continue
        # end

        @fastmath begin
            @inbounds begin
                # t = times[ii] #? not used
                a = friction(v, vt) - 100.0*x
                v = v + a * dt
                x = x + v * dt
                positions[ii] = x/x0
            end
        end
    end
    (times, positions)
end

```

---

<div class="post-metadata">

**Author:** ![Iulian.Cioarca](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iulian.cioarca/32/30166_2.png) [@Iulian.Cioarca](https://discourse.julialang.org/u/Iulian.Cioarca)\
**Post date:** [January 11, 2020, 8:33am UTC](https://discourse.julialang.org/t/how-to-optimize-the-following-code/33209/7 "2020-01-11T08:33:39Z")

</div>

Awesome! Thank you all for the nice suggestions!

---

<div class="post-metadata">

**Author:** ![safijari](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/safijari/32/15184_2.png) [@safijari](https://discourse.julialang.org/u/safijari)\
**Post date:** [January 11, 2020, 11:55pm UTC](https://discourse.julialang.org/t/how-to-optimize-the-following-code/33209/8 "2020-01-11T23:55:35Z")

</div>

I’m the author of the video and would like to clarify one potential point of miscommunication: the intent of the video was not to compare Julia with python/numba. The only reason the comparison happened was because one of my subscribers had asked for it.

With that out of the way, a big thanks to everyone that has responded with suggestions for improvements. This bit of code was written in hour 3 of me becoming familiar with Julia so it’s very illuminating to see what I missed.
