# Why is this Julia code considerably slower than Matlab

**URL:** <https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365>\
**Category:** New to Julia\
**Tags:** performance\
**Created:** [February 28, 2017, 3:03pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365 "2017-02-28T15:03:36Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![zsoerenm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zsoerenm/32/664_2.png) [@zsoerenm](https://discourse.julialang.org/u/zsoerenm)\
**Post date:** [February 28, 2017, 3:03pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365/1 "2017-02-28T15:03:37Z")

</div>

If I compare this Julia code:

```julia
module Testing

  function performance_test()
    range = 1:2000000;

    steering_vectors = complex(randn(4,11), randn(4,11));

    sum_signal = zeros(Complex{Float64}, 4, length(range));
    for i = 1:11
        carrier_signal = map(x -> exp(2im * pi * 1.023e6 * x / 4e6 + 1im * 40 * pi / 180), range);
        # carrier_signal = exp(2im * pi * 1.023e6 * range / 4e6 + 1im * 40 * pi / 180);
        steered_signal = steering_vectors[:,i] * carrier_signal.';
        sum_signal = sum_signal + steered_signal;
    end
    return sum_signal;
  end

end

```

against this Matlab code:

```julia
range = 1:2000000;

steering_vectors = complex(randn(4,11), randn(4,11));

sum_signal = zeros(4,length(range));
for i = 1:11
    carrier_signal = exp(2i * pi * 1.023e6 * range / 4e6 + 1i * 40 * pi / 180);
    steered_signal = steering_vectors(:,i) * carrier_signal;
    sum_signal = sum_signal + steered_signal;
end

```

I get the following results:

- Julia: 3.956940 seconds (207 allocations: 3.397 GB, 19.13% gc time)
- Matlab: Elapsed time is 1.623101 seconds (Allocated Memory: 62714.44 Kb)

The array transposition in Julia takes only a small amount of time compared to the rest when viewing ProfileView.view().

How can I get similiar results to Matlab?

---

<div class="post-metadata">

**Author:** ![lobingera](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lobingera/32/211_2.png) [@lobingera](https://discourse.julialang.org/u/lobingera)\
**Post date:** [February 28, 2017, 3:18pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365/2 "2017-02-28T15:18:41Z")

</div>

> [@zsoerenm](#):
>
> How can I get similiar results to Matlab?

This could be again one of the multi-threading (matlab default) vs. single threading (julia default) cases in observation.

But one comment: Don’t use i as loop counter in matlab when you use it also as imaginary unit (like in your exp(2i \* pi \* …)

---

<div class="post-metadata">

**Author:** ![NickNack](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nicknack/32/1792_2.png) [@NickNack](https://discourse.julialang.org/u/NickNack)\
**Post date:** [February 28, 2017, 3:39pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365/3 "2017-02-28T15:39:52Z")

</div>

Also, as the code stands you can speed up both versions considerably by moving the `carrier_signal` assignment outside the loop.

---

<div class="post-metadata">

**Author:** ![zsoerenm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zsoerenm/32/664_2.png) [@zsoerenm](https://discourse.julialang.org/u/zsoerenm)\
**Post date:** [February 28, 2017, 3:43pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365/4 "2017-02-28T15:43:52Z")

</div>

Oh yeah, sure. I simplified my code, to the code above. In my actual code I can not move carrier\_signal outside the first loop, because it depends on i.

---

<div class="post-metadata">

**Author:** ![zsoerenm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zsoerenm/32/664_2.png) [@zsoerenm](https://discourse.julialang.org/u/zsoerenm)\
**Post date:** [February 28, 2017, 3:54pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365/5 "2017-02-28T15:54:56Z")

</div>

When I use pmap for the first loop using all available processors with julia -p7:

```julia
module Testing

  function performance_test()
    range = 1:2000000;

    steering_vectors = complex(randn(4,11), randn(4,11));
    signals = pmap(1:11) do i
        carrier_signal = map(x -> exp(2im * pi * 1.023e6 * x / 4e6 + 1im * 40 * pi / 180), range);
        steered_signal = steering_vectors[:,i] * carrier_signal.';
    end
    return sum(signals);
  end

end

```

I get:

- Julia: 2.433277 seconds (10.97 k allocations: 2.504 GB, 18.81% gc time)

But this is still slower than 1.679762 seconds from Matlab (with corrected loop variable i)

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [February 28, 2017, 4:20pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365/6 "2017-02-28T16:20:45Z")

</div>

50% is spent in `sin` and `cos` so perhaps look at [https://github.com/JuliaMath/VML.jl](https://github.com/JuliaMath/VML.jl) or [https://github.com/JuliaMath/Yeppp.jl](https://github.com/JuliaMath/Yeppp.jl). Does your timings for Matlab change a lot if you let it run with one thread?

---

<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:** [February 28, 2017, 4:29pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365/7 "2017-02-28T16:29:08Z")

</div>

> [@zsoerenm](#):
>
> Julia: 3.956940 seconds (207 allocations: 3.397 GB, 19.13% gc time)  
> Matlab: Elapsed time is 1.623101 seconds (Allocated Memory: 62714.44 Kb)

Why is Julia allocating so much more? There must be an issue somewhere. The same algorithm should allocate similar amounts.

---

<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:** [February 28, 2017, 4:35pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365/8 "2017-02-28T16:35:48Z")

</div>

Matlab is probably doing some in-place updates under the hood, while the Julia code doesn’t do 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:** [February 28, 2017, 4:39pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365/9 "2017-02-28T16:39:37Z")

</div>

Here’s how I would’ve written it:

```julia
module Testing

  using InplaceOps 
  
  function performance_test()
    range = 1:2000000
    range_transp = range'
    steering_vectors = complex(randn(4,11), randn(4,11))
    steered_signal = zeros(Complex{Float64}, 4, length(range))
    sum_signal = zeros(Complex{Float64}, 4, length(range))
    for i = 1:11
        carrier_signal = map(x -> exp(2im * pi * 1.023e6 * x / 4e6 + 1im * 40 * pi / 180), range')
        # carrier_signal = exp(2im * pi * 1.023e6 * range / 4e6 + 1im * 40 * pi / 180)
        @into! steered_signal = @view(steering_vectors[:,i]) * carrier_signal
        for i in eachindex(steered_signal)
          sum_signal[i] = sum_signal[i] + steered_signal[i]
        end
    end
    return sum_signal
  end

end

```

On my computer, that changes it from 7.5 seconds to 4 seconds. Depends on how much memory you have.

Since there’s a matrix multiplication in there, the difference between MKL and OpenBLAS might be showing up again?

---

<div class="post-metadata">

**Author:** ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)\
**Post date:** [February 28, 2017, 4:41pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365/10 "2017-02-28T16:41:08Z")

</div>

What is the allocations for that code?

---

<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:** [February 28, 2017, 4:42pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365/11 "2017-02-28T16:42:02Z")

</div>

Goes from

```julia
  7.520755 seconds (732.83 k allocations: 3.417 GB, 23.79% gc time)

```

to

```julia
  4.818585 seconds (27.87 k allocations: 764.075 MB, 2.71% gc time)

```

I haven’t done much with it. I just pooped out some optimizations without much testing, so it can probably be made better.

---

<div class="post-metadata">

**Author:** ![piever](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/piever/32/1815_2.png) [@piever](https://discourse.julialang.org/u/piever)\
**Post date:** [February 28, 2017, 4:44pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365/12 "2017-02-28T16:44:02Z")

</div>

Also, to cut down on the allocations, one could use the in-place version of `map`, i.e.

`map!(x -> exp(2im * pi * 1.023e6 * x / 4e6 + 1im * 40 * pi / 180), carrier_signal, range_transp)`

---

<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:** [February 28, 2017, 4:44pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365/13 "2017-02-28T16:44:48Z")

</div>

Or on v0.6 just use broadcast fusion.

---

<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:** [February 28, 2017, 4:46pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365/14 "2017-02-28T16:46:24Z")

</div>

Full devectorization

```julia
    N = 2000000
    range = 1:N
    
    steering_vectors = complex(randn(4,11), randn(4,11))
    
    sum_signal = zeros(Complex{Float64}, 4, length(range))
    carrier_signal = zeros(Complex{Float64}, length(range))
    for i = 1:11
        for k = 1:N
            carrier_signal[k] = exp(2im * pi * 1.023e6 * range[k] / 4e6 + 1im * 40 * pi / 180)
        end

        for j = 1:4
            for k = 1:N
                sum_signal[j,k] += steering_vectors[j,i] * carrier_signal[k]
            end
        end
    end
    return sum_signal

```

brings it down on my computer from  
`8.143687 seconds (207 allocations: 3.397 GB, 8.29% gc time)`  
to  
`3.646278 seconds (11 allocations: 152.590 MB, 0.22% gc time)`

Not really tested code so hopefully it computes the same thing.

---

<div class="post-metadata">

**Author:** ![RoyiAvital](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/royiavital/32/571_2.png) [@RoyiAvital](https://discourse.julialang.org/u/RoyiAvital)\
**Post date:** [February 28, 2017, 5:29pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365/15 "2017-02-28T17:29:57Z")

</div>

Wow!

This is a code with loop and MATLAB is better?

Which version of MATLAB are you using?  
Did you put inside a function when testing in MATLAB?

I’d pay attention to the amount of memory consumed.  
MATLAB is doing much better in that department.

@ChrisRackauckas,  
Your example is exactly what shouldn’t happen.  
Very clean and simple code become messy to generate some performance where it still loses to MATLAB on a loop.

I’d say, based on memory, MATLAB intelligently create a more efficient code (Less memory work).  
Looking at the better memory allocation I’d say it is not all because of Multi Threading (Easy to blame but not right thing to do).

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [February 28, 2017, 5:55pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365/16 "2017-02-28T17:55:04Z")

</div>

> [@RoyiAvital](#):
>
> This is a code with loop and MATLAB is better?

No it’s not a loop.

> [@RoyiAvital](#):
>
> I’d pay attention to the amount of memory consumed.

Yes, though allocating big arrays this way isn’t the problem. It’s cheap compared to the computation of `exp(::Complex128)`

> [@RoyiAvital](#):
>
> Looking at the better memory allocation I’d say it is not all because of Multi Threading (Easy to blame but not right thing to do).

Yes it is multithreading. As already pointed out, most of the time is spent in the `exp` (or `sin` and `cos`) functions and as I tested locally on MATLAB 2016b it is certainly using 4 physical cores for that.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [February 28, 2017, 6:04pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365/17 "2017-02-28T18:04:24Z")

</div>

After increasing the count to 101 instead of 11. I get 11s on matlab and 44s on julia. With julia with 4 threads, I get 26s with openlibm, and 9s with system libm. The difference between the two libm versions is a known issue [https://github.com/JuliaLang/julia/issues/17395](https://github.com/JuliaLang/julia/issues/17395) . It’s unclear what’s triggering it…

---

<div class="post-metadata">

**Author:** ![RoyiAvital](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/royiavital/32/571_2.png) [@RoyiAvital](https://discourse.julialang.org/u/RoyiAvital)\
**Post date:** [February 28, 2017, 6:07pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365/18 "2017-02-28T18:07:12Z")

</div>

@yuyichao,

I wasn’t saying MATLAB doesn’t use Multi Threading.  
I was just saying this is MATLAB vs. Julia from a user stand of point, why would he mark this against MATLAB?

The thing is under a loop and MATLAB used to be very bad in those cases.

The low memory consumption tells me that besides the MT MATLAB created (Maybe?) more efficient code.  
I’m not an expert, but if the memory is low it means less intermediate data is created, isn’t that a symptom for something?  
I’d like to see the same memory consumption and performance as in the Devectorized code, or at least close to that.

Hopefully this kind of code will be (Significantly) faster in Julia 0.6.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [February 28, 2017, 6:09pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365/19 "2017-02-28T18:09:50Z")

</div>

> [@RoyiAvital](#):
>
> I wasn’t saying MATLAB doesn’t use Multi Threading.

Well, you said it wasn’t the issue but in fact it is.

> [@RoyiAvital](#):
>
> The thing is under a loop and MATLAB used to be very bad in those cases.

It used to be bad for cheap loops with many iterations. This is nothing closed to that.

> [@RoyiAvital](#):
>
> The low memory consumption tells me that besides the MT MATLAB created (Maybe?) more efficient code.I’m not an expert, but if the memory is low it means less intermediate data is created, isn’t that a symptom for something?

Correct, but that’s not the issue here and that’s why the more generic loop fusion syntax in 0.5 + 0.6 is for that’s already mentioned earlier in the thread.

---

<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:** [February 28, 2017, 6:17pm UTC](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365/20 "2017-02-28T18:17:54Z")

</div>

> [@RoyiAvital](#):
>
> The thing is under a loop and MATLAB used to be very bad in those cases.

Not this kind of loop. The “devectorized” loops? Yes. Looping over a bunch of vectorized operations? That’s fine.

Note that we also haven’t re-run the MATLAB code… and our Julia code has halved in its time. So we’re likely about even now.

[Next page](https://discourse.julialang.org/t/why-is-this-julia-code-considerably-slower-than-matlab/2365.md?page=2)
