# Improving Performance of this Code

**URL:** <https://discourse.julialang.org/t/improving-performance-of-this-code/31326>\
**Category:** Performance\
**Tags:** economics, loops\
**Created:** [November 20, 2019, 10:00pm UTC](https://discourse.julialang.org/t/improving-performance-of-this-code/31326 "2019-11-20T22:00:26Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![jmcastro2109](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmcastro2109/32/38427_2.png) [@jmcastro2109](https://discourse.julialang.org/u/jmcastro2109)\
**Post date:** [November 20, 2019, 10:00pm UTC](https://discourse.julialang.org/t/improving-performance-of-this-code/31326/1 "2019-11-20T22:00:26Z")

</div>

Hello!

I am trying to solve a big model and at the core I have the following loop which essentially solves a Backward Induction Problem. In what follows I provide a MWE.

In my model, I am solving this problem many many times and therefore I would like to push its performance to the max, however, at this point I do not know how to improve it further.

I believe I can make improvements both in terms of memory usage and computation speed. Any suggestions are welcome.

```julia
using Distributed
using BenchmarkTools
using ProgressMeter
using BitOperations
using Profile
using Traceur

addprocs(11, exeflags="--project=.")

@everywhere J = 100
@everywhere T = 200
@everywhere Π = 10*rand(J,T)
@everywhere Dᵢ = rand([0],J,1)
@everywhere Sj = 20*rand(J,T)
@everywhere Fj = 20*rand(J,T)

@everywhere Π=Π.-Sj

@everywhere function myfun1(Π,Fj,Sj,Dᵢ,β,J,T)
                D = zeros(Int64,2,T,J)
                v = zeros(Float64,2,T,J)
                Dstar = zeros(Int64,J,T+1)
                Dstar[:,1]=Dᵢ
                S = [0 1]
                Πstar=0
                @inbounds for t=0:T-1, j=1:J, i=1:2
                    if t==0
                        payoff = Π[j,T-t]+Sj[j,T-t]*S[i]
                        D[i,T-t,j]=(payoff>0)
                        v[i,T-t,j]=D[i,T-t,j]*payoff
                    else
                        payoff_enter = Π[j,T-t]+Sj[j,T-t]*S[i]+β*v[2,T-t+1,j]
                        payoff_exit = β*v[1,T-t+1,j]
                        d=(payoff_enter>payoff_exit)
                        D[i,T-t,j] = d
                        v[i,T-t,j]=d*(payoff_enter)+(1-d)*payoff_exit
                    end
                end
                #println(v)
                @inbounds for t=2:T+1, j=1:J
                        Dstar[j,t]=D[Dstar[j,t-1]+1,t-1,j]
                end
                Dstar = Dstar[:,2:end]
                return Dstar
end

println("TIMES")
f1 = @btime myfun1(Π,Fj,Sj,Dᵢ,0.9,J,T)

@profile myfun1(Π,Fj,Sj,Dᵢ,0.9,J,T)

@trace myfun1(Π,Fj,Sj,Dᵢ,0.9,J,T)

```

Any suggestion will be very much appreciated!

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [November 20, 2019, 10:06pm UTC](https://discourse.julialang.org/t/improving-performance-of-this-code/31326/2 "2019-11-20T22:06:03Z")

</div>

Thank you for the MWE. Would you mind formatting and indenting your code to make it easier for us to read and help? I great guide on this can be found here: [Please read: make it easier to help you](https://discourse.julialang.org/t/psa-make-it-easier-to-help-you/14757)

---

<div class="post-metadata">

**Author:** ![jmcastro2109](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmcastro2109/32/38427_2.png) [@jmcastro2109](https://discourse.julialang.org/u/jmcastro2109)\
**Post date:** [November 20, 2019, 10:08pm UTC](https://discourse.julialang.org/t/improving-performance-of-this-code/31326/3 "2019-11-20T22:08:42Z")

</div>

I am really sorry! Here it is

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [November 20, 2019, 10:23pm UTC](https://discourse.julialang.org/t/improving-performance-of-this-code/31326/4 "2019-11-20T22:23:26Z")

</div>

So first off, you seem to spawn a bunch of julia processes at the start and spread your definitions to those processed with `@everywhere` but I never see any actual parallel computing in this code. Am I missing something, or did you forget to make a loop parallel?

---

<div class="post-metadata">

**Author:** ![jmcastro2109](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmcastro2109/32/38427_2.png) [@jmcastro2109](https://discourse.julialang.org/u/jmcastro2109)\
**Post date:** [November 20, 2019, 10:39pm UTC](https://discourse.julialang.org/t/improving-performance-of-this-code/31326/5 "2019-11-20T22:39:55Z")

</div>

You’re right I am not parallelizing anything.This code is embedded into some other parallel which I run in parallel, but here it does not play any role.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [November 20, 2019, 10:59pm UTC](https://discourse.julialang.org/t/improving-performance-of-this-code/31326/6 "2019-11-20T22:59:10Z")

</div>

As a first pass, I was able to shave a third off the runtime by simply putting your two sets of for loops into separate functions:

```julia
function myfun2(Π,Fj,Sj,Dᵢ,β,J,T)
    D = zeros(Int64,2,T,J)
    v = zeros(Float64,2,T,J)
    Dstar = zeros(Int64,J,T+1)
    Dstar[:,1]=Dᵢ
    S = [0 1]
    Πstar=0
    func2inner1!(Π, Sj, S, D, v, β, J, T)
    funct2inner2!(Dstar, D, T, J)
end

function func2inner1!(Π, Sj, S, D, v, β, J, T)
    @inbounds for t ∈ 0:T-1, j ∈ 1:J, i ∈ 1:2
        if t==0
            payoff = Π[j,T-t]+Sj[j,T-t]*S[i]
            D[i,T-t,j] = (payoff>0)
            v[i,T-t,j] = D[i,T-t,j]*payoff
        else
            payoff_enter = Π[j,T-t]+Sj[j,T-t]*S[i]+β*v[2,T-t+1,j]
            payoff_exit = β*v[1,T-t+1,j]
            d=(payoff_enter>payoff_exit)
            D[i,T-t,j] = d
            v[i,T-t,j] = d*(payoff_enter)+(1-d)*payoff_exit
        end
    end
end

function funct2inner2!(Dstar, D, T, J)
    @inbounds for t=2:T+1, j=1:J
        Dstar[j,t]=D[Dstar[j,t-1]+1,t-1,j]
    end
    Dstar = Dstar[:,2:end]
end

```

```julia
julia> f1 = @btime myfun1($Π,$Fj,$Sj, $Dᵢ, $(0.9), $J, $T);
  342.202 μs (9 allocations: 938.72 KiB)

julia> f2 = @btime myfun2($Π,$Fj,$Sj, $Dᵢ, $(0.9), $J, $T);
  265.630 μs (9 allocations: 938.72 KiB)

julia> f1 == f2
true

```

I’m sure there’s more performance to be had here, but it’s a little hard without knowing what exactly this function is doing. For instance, your iteration order is inefficient. You want to be accessing your arrays column, first then row. More performance tips can be found here: [Performance Tips · The Julia Language](https://docs.julialang.org/en/v1/manual/performance-tips/index.html)

---

<div class="post-metadata">

**Author:** ![jmcastro2109](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmcastro2109/32/38427_2.png) [@jmcastro2109](https://discourse.julialang.org/u/jmcastro2109)\
**Post date:** [November 21, 2019, 1:51pm UTC](https://discourse.julialang.org/t/improving-performance-of-this-code/31326/7 "2019-11-21T13:51:59Z")

</div>

Thanks. This is very useful

---

<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:** [November 21, 2019, 2:23pm UTC](https://discourse.julialang.org/t/improving-performance-of-this-code/31326/8 "2019-11-21T14:23:31Z")

</div>

Minor nitpick:

> [@Mason](#):
>
> ```julia
> function funct2inner2!(Dstar, D, T, J)
> @inbounds for t=2:T+1, j=1:J
> Dstar[j,t]=D[Dstar[j,t-1]+1,t-1,j]
> end
> Dstar = Dstar[:,2:end]
> end
> 
> ```

The last assignment isn’t actually doing anything useful. This only works out right thanks to implicit return of the last computed value.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [November 21, 2019, 5:40pm UTC](https://discourse.julialang.org/t/improving-performance-of-this-code/31326/9 "2019-11-21T17:40:48Z")

</div>

@GunnarFarneback I’m not sure what you mean by “not doing anything useful”. It’s dropping a column which is required for the correct output. It’s not mutating `Dstar` if that’s what you mean, but neither does the original implementation. Are you just objecting to me not writing the unnecessary ‘return’ statement?

---

<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:** [November 21, 2019, 5:59pm UTC](https://discourse.julialang.org/t/improving-performance-of-this-code/31326/10 "2019-11-21T17:59:08Z")

</div>

The assignment is unnecessary. You could just write

```julia
return Dstar[:,2:end]

```

BTW, `return` is not unnecessary, it really helps readability.

---

<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:** [November 21, 2019, 6:07pm UTC](https://discourse.julialang.org/t/improving-performance-of-this-code/31326/11 "2019-11-21T18:07:27Z")

</div>

I’m objecting to assigning a new binding to `Dstar`, which then immediately goes out of scope without affecting anything. Try adding `return Dstar` at the end of `myfun2` (without changing anything else) to see what I mean.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [November 21, 2019, 6:21pm UTC](https://discourse.julialang.org/t/improving-performance-of-this-code/31326/12 "2019-11-21T18:21:07Z")

</div>

> [@GunnarFarneback](#):
>
> I’m objecting to assigning a new binding to `Dstar` , which then immediately goes out of scope without affecting anything.

Oh yeah, that unnecessary assignment just comes from the fact that I was just copy pasting and moving around the OP’s code. I made some minor stylistic tweaks like removing `return` but didn’t go through any great effort to be consistent or thorough. I definitely wouldn’t normally do that unnecessary assignment in my own code, but I generally disagree with `return` statements unless actually necessary for things like short circuiting.

This is pretty off topic though, I just wanted to make sure there wasn’t some actual technical issue that I had missed,

---

<div class="post-metadata">

**Author:** ![Oscar](https://avatars.discourse-cdn.com/v4/letter/o/22d042/32.png) [@Oscar](https://discourse.julialang.org/u/Oscar)\
**Post date:** [November 22, 2019, 11:59am UTC](https://discourse.julialang.org/t/improving-performance-of-this-code/31326/13 "2019-11-22T11:59:25Z")

</div>

That’s interesting. Could you perhaps provide some intuition for why separating the two for loops in separate functions increases performance?
