# Puzzling performance when multiplying real and complex matrices

**URL:** <https://discourse.julialang.org/t/puzzling-performance-when-multiplying-real-and-complex-matrices/20689>\
**Category:** General Usage\
**Created:** [February 12, 2019, 2:06am UTC](https://discourse.julialang.org/t/puzzling-performance-when-multiplying-real-and-complex-matrices/20689 "2019-02-12T02:06:21Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [February 12, 2019, 2:06am UTC](https://discourse.julialang.org/t/puzzling-performance-when-multiplying-real-and-complex-matrices/20689/1 "2019-02-12T02:06:21Z")

</div>

Perhaps the following puzzle will ring a bell for someone?

Multiply `mul!(H, B, Gamma)`:

```julia
    (eltype(H), eltype(B), eltype(Gamma)) = (Complex{Float64}, Complex{Float64}, Complex{Float64})   

```

It takes 13.091117 seconds

Multiply `mul!(Vn, Gamma, P)`:

```julia
    (eltype(Vn), eltype(Gamma), eltype(P), size(Gamma), size(P)) = (Complex{Float64}, Complex{Float64}, Complex{Float64}, (4436, 4436), (4436, 181))                

```

It takes 0.643775 seconds

Now we change `Gamma` to be real, everything else is the same.

```julia
      (eltype(H), eltype(B), eltype(Gamma)) = (Complex{Float64}, Complex{Float64}, Float64)         

```

The timing for the first product _decreased_ with more than a factor of two (4.532288 seconds).

The timing for the second product _increased_ by about a factor of 8:

```julia
      (eltype(Vn), eltype(Gamma), eltype(P), size(Gamma), size(P)) = (Complex{Float64}, Float64, Complex{Float64}, (4436, 4436), (4436, 181))       

```

This takes 4.958194 seconds (6 allocations: 336 bytes)

I could track it down to `_generic_matmatmul!`. I believe tiled execution is selected. (There are some scary `# FIXME: This code is completely invalid!!!` warnings around!) But that’s where I got stuck. I don’t see why changing the type of one of the arrays should speed up one product and slow down another one.

---

<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:** [February 12, 2019, 7:11am UTC](https://discourse.julialang.org/t/puzzling-performance-when-multiplying-real-and-complex-matrices/20689/2 "2019-02-12T07:11:45Z")

</div>

Can you provide a MWE that one can copy and run?

---

<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 12, 2019, 7:14am UTC](https://discourse.julialang.org/t/puzzling-performance-when-multiplying-real-and-complex-matrices/20689/3 "2019-02-12T07:14:46Z")

</div>

[https://github.com/JuliaLang/julia/issues/20060](https://github.com/JuliaLang/julia/issues/20060)  
[https://github.com/JuliaLang/julia/issues/30811](https://github.com/JuliaLang/julia/issues/30811)

Perhaps

---

<div class="post-metadata">

**Author:** ![PetrKryslUCSD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petrkryslucsd/32/215825_2.png) [@PetrKryslUCSD](https://discourse.julialang.org/u/PetrKryslUCSD)\
**Post date:** [February 12, 2019, 3:12pm UTC](https://discourse.julialang.org/t/puzzling-performance-when-multiplying-real-and-complex-matrices/20689/5 "2019-02-12T15:12:39Z")

</div>

These are useful links Kristoffer, thanks. In fact [Matrix product between a real and a complex matrix · Issue #30811 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/30811) turned out to describe the reason for the speed up/ slow down problem. The gist: if one has a complex matrix and a real matrix, they will be processed by BLAS if the product is `complex*real`, otherwise by the generic matmul for `real*complex`.
