# LinearAlgebra.inv matrix inversion slower than MATLAB?

**URL:** <https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066>\
**Category:** Performance\
**Tags:** performance\
**Created:** [October 19, 2021, 9:05pm UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066 "2021-10-19T21:05:04Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![pitsianis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pitsianis/32/26588_2.png) [@pitsianis](https://discourse.julialang.org/u/pitsianis)\
**Post date:** [October 19, 2021, 9:05pm UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066/1 "2021-10-19T21:05:04Z")

</div>

Why a matrix inversion is slower than MATLAB?

I am comparing `julia 1.6.3 (2021-09-23) Built by Homebrew (v1.6.3_1)` and `MATLAB 9.11.0.1769968 (R2021b)` on a late 2013 MacBook Pro 2.6 GHz Dual-Core Intel Core i5 with 16 GB 1600 MHz DDR3.

The simplistic and unscientific test is

```matlab
>> A = rand(4000); f = @() inv(A); timeit(f)

ans =

    2.1841

```

And

```julia
julia> using LinearAlgebra, BenchmarkTools

julia> function test(n)
         A = rand(n,n)
         @btime inv($A)
       end
test (generic function with 1 method)

julia> test(4000);
  3.932 s (5 allocations: 124.04 MiB)

```

The time difference is very significant, did the homebrew binary not link to the proper fast libraries?

---

<div class="post-metadata">

**Author:** ![albheim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albheim/32/34660_2.png) [@albheim](https://discourse.julialang.org/u/albheim)\
**Post date:** [October 19, 2021, 9:38pm UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066/2 "2021-10-19T21:38:08Z")

</div>

Seems like in the julia one you are timing both the generation and inversion, and matlab only the inversion. I’m on the phone so can’t test if that will be any relevant part of the total time, but feels like it could be.

Also you can try running it multiple times to see if compilation was part of that time.

EDIT: I misread the code, blame being tired and as mentioned on the phone…

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [October 19, 2021, 9:47pm UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066/3 "2021-10-19T21:47:57Z")

</div>

From [here](https://discourse.julialang.org/t/libraries-invoked-by-julia/14164): check

```julia
using LinearAlgebra
LinearAlgebra.versioninfo()

```

On my system:

```julia
BLAS: libopenblas (OpenBLAS 0.3.10 USE64BITINT DYNAMIC_ARCH NO_AFFINITY Prescott MAX_THREADS=32)
LAPACK: libopenblas64_

```

---

<div class="post-metadata">

**Author:** ![pitsianis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pitsianis/32/26588_2.png) [@pitsianis](https://discourse.julialang.org/u/pitsianis)\
**Post date:** [October 19, 2021, 9:57pm UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066/4 "2021-10-19T21:57:09Z")

</div>

> [@goerch](#):
>
> `LinearAlgebra.versioninfo()`

I get

```julia
julia> LinearAlgebra.versioninfo()
BLAS: libopenblas (OpenBLAS 0.3.17 DYNAMIC_ARCH NO_AFFINITY USE_OPENMP Haswell MAX_THREADS=56)
LAPACK: libopenblas

```

How can get Julia to use the MKL library?

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [October 19, 2021, 10:00pm UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066/5 "2021-10-19T22:00:40Z")

</div>

First hit on the search engine without name is [GitHub - JuliaLinearAlgebra/MKL.jl: Intel MKL linear algebra backend for Julia](https://github.com/JuliaLinearAlgebra/MKL.jl). Looks reasonably trustworthy.

---

<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:** [October 19, 2021, 10:18pm UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066/6 "2021-10-19T22:18:19Z")

</div>

as always, it’s worth noting that you should pretty much never use matrix inversion. instead, use \ for backsolves, or factorizations. both approaches will be faster and have lower error.

---

<div class="post-metadata">

**Author:** ![goerch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerch/32/29122_2.png) [@goerch](https://discourse.julialang.org/u/goerch)\
**Post date:** [October 19, 2021, 10:22pm UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066/7 "2021-10-19T22:22:49Z")

</div>

Only exception I vaguely remember is multiple right hand sides (but still lower error sounds right)…

---

<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:** [October 19, 2021, 10:25pm UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066/8 "2021-10-19T22:25:30Z")

</div>

The MKL.jl experience is particularly nice on Julia \>= 1.7 where it is based on [libblastrampoline](https://github.com/JuliaLinearAlgebra/libblastrampoline) (and [MKL\_jll.jl](https://github.com/JuliaBinaryWrappers/MKL_jll.jl)). In this case, you can simply compare the performance of `inv` from OpenBLAS and MKL:

```julia
julia> using LinearAlgebra

julia> using BenchmarkTools

julia> A = rand(4000,4000);

julia> BLAS.get_config()
LinearAlgebra.BLAS.LBTConfig
Libraries:
└ [ILP64] libopenblas64_.0.3.13.dylib

julia> @btime inv($A);
  1.444 s (6 allocations: 124.05 MiB)

julia> using MKL

julia> BLAS.get_config()
LinearAlgebra.BLAS.LBTConfig
Libraries:
└ [ILP64] libmkl_rt.1.dylib

julia> @btime inv($A);
  846.798 ms (6 allocations: 139.68 MiB)

```

---

<div class="post-metadata">

**Author:** ![pitsianis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pitsianis/32/26588_2.png) [@pitsianis](https://discourse.julialang.org/u/pitsianis)\
**Post date:** [October 19, 2021, 10:42pm UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066/9 "2021-10-19T22:42:40Z")

</div>

Indeed, with MKL the time becomes

```julia
julia> test(4000);
  2.158 s (5 allocations: 139.66 MiB)

```

Thanks!

---

<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:** [October 19, 2021, 11:45pm UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066/10 "2021-10-19T23:45:02Z")

</div>

multiple right hand sides are when the best option is to factorize the matrix, and perform the perform solves with the factored version. The time will be comparable to `inv`, but the result will be more accurate.

---

<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:** [October 20, 2021, 2:44am UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066/11 "2021-10-20T02:44:14Z")

</div>

> [@goerch](#):
>
> Only exception I vaguely remember is multiple right hand sides (but still lower error sounds right)…

Actually the lower accuracy is not accurate ;-).  
When the inversion is done properly there is no reason for lower accuracy.  
See, for example, [How Accurate Is `inv(A)*b`](https://arxiv.org/abs/1201.6035)?  
Performance wise, it is better to stick with decompositions.

@Oscar_Smith , You may be interested in reading this as well.

---

<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:** [October 20, 2021, 2:59am UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066/12 "2021-10-20T02:59:09Z")

</div>

`inv` is a constant factor more expensive than factorization, and hence rather useless for anything more than a handful of rows and columns, though.

---

<div class="post-metadata">

**Author:** ![Seif\_Shebl](https://avatars.discourse-cdn.com/v4/letter/s/eada6e/32.png) [@Seif\_Shebl](https://discourse.julialang.org/u/Seif_Shebl)\
**Post date:** [October 20, 2021, 6:52pm UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066/13 "2021-10-20T18:52:06Z")

</div>

I see no real difference here even with openblas:

```julia
MATLAB R2020a:
>> A = rand(4000); f = @() inv(A); timeit(f)
ans =
       1.2232

julia> test(4000);
  1.249 s (6 allocations: 124.05 MiB)

julia> VERSION
v"1.7.0-rc1"

julia> BLAS.get_config()
LinearAlgebra.BLAS.LBTConfig
Libraries:
└ [ILP64] libopenblas64_.dll

```

That said, you practically rarely want to calculate matrix inverse explicitely as others noted.

---

<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:** [October 20, 2021, 8:23pm UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066/14 "2021-10-20T20:23:16Z")

</div>

What type of CPU are you using? MKL usually only beats OpenBLAS on Intel CPUs

---

<div class="post-metadata">

**Author:** ![Seif\_Shebl](https://avatars.discourse-cdn.com/v4/letter/s/eada6e/32.png) [@Seif\_Shebl](https://discourse.julialang.org/u/Seif_Shebl)\
**Post date:** [October 20, 2021, 8:46pm UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066/16 "2021-10-20T20:46:23Z")

</div>

Yes, it’s an old-ish Intel CPU (Haswell), and I used to notice some edge in favor of MKL in the past, but with recent Julia versions this edge is more like within the margin of error. May be I can test again with MKL and come back with MKL results in Julia.

```julia
julia> versioninfo()
Julia Version 1.7.0-rc1
Commit 9eade6195e (2021-09-12 06:45 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-12.0.1 (ORCJIT, haswell)
Environment:
  JULIA_DEPOT_PATH = D:\DeepBook\.julia

```

---

<div class="post-metadata">

**Author:** ![rveltz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rveltz/32/2707_2.png) [@rveltz](https://discourse.julialang.org/u/rveltz)\
**Post date:** [October 20, 2021, 8:59pm UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066/17 "2021-10-20T20:59:05Z")

</div>

Out of curiosity. In MATLAB you can invert a vector? (e.g rand(4000))

---

<div class="post-metadata">

**Author:** ![stephenll](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephenll/32/28751_2.png) [@stephenll](https://discourse.julialang.org/u/stephenll)\
**Post date:** [October 20, 2021, 9:03pm UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066/18 "2021-10-20T21:03:42Z")

</div>

Unfortunately, in MATLAB, calling rand(4000) is a shortcut for creating a 4000x4000.

---

<div class="post-metadata">

**Author:** ![zdenek\_hurak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zdenek_hurak/32/53118_2.png) [@zdenek\_hurak](https://discourse.julialang.org/u/zdenek_hurak)\
**Post date:** [October 20, 2021, 9:07pm UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066/19 "2021-10-20T21:07:14Z")

</div>

No.

```matlab
>> A = rand(1000,1);
>> inv(A)
Error using inv
Matrix must be square.

```

---

<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:** [October 20, 2021, 9:13pm UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066/20 "2021-10-20T21:13:01Z")

</div>

> [@stephenll](#):
>
> Unfortunately, in MATLAB, calling rand(4000) is a shortcut for creating a 4000x4000.

😱

---

<div class="post-metadata">

**Author:** ![Seif\_Shebl](https://avatars.discourse-cdn.com/v4/letter/s/eada6e/32.png) [@Seif\_Shebl](https://discourse.julialang.org/u/Seif_Shebl)\
**Post date:** [October 20, 2021, 9:33pm UTC](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066/21 "2021-10-20T21:33:04Z")

</div>

OK, with MKL.jl I see about 12% improvement over openblas, still better than MATLAB’s MKL.

```julia
julia> BLAS.get_config()
LinearAlgebra.BLAS.LBTConfig
Libraries:
└ [ILP64] libopenblas64_.dll

julia> test(4000);
  1.206 s (6 allocations: 124.05 MiB)

julia> using MKL

julia> BLAS.get_config()
LinearAlgebra.BLAS.LBTConfig
Libraries:
└ [ILP64] mkl_rt.1.dll

julia> test(4000);
  1.075 s (6 allocations: 139.68 MiB)

```

[Next page](https://discourse.julialang.org/t/linearalgebra-inv-matrix-inversion-slower-than-matlab/70066.md?page=2)
