# Would matrix multiplication benefit if Julia allowed for row-major arrays as well?

**URL:** https://discourse.julialang.org/t/would-matrix-multiplication-benefit-if-julia-allowed-for-row-major-arrays-as-well/15214
**Category:** Internals & Design
**Tags:** question, proposal, column-major
**Created:** [September 20, 2018, 6:23am UTC](https://discourse.julialang.org/t/would-matrix-multiplication-benefit-if-julia-allowed-for-row-major-arrays-as-well/15214 "2018-09-20T06:23:04Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![AdamR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adamr/32/5109_2.png) [@AdamR](https://discourse.julialang.org/u/AdamR)
#### Post date: [September 20, 2018, 6:23am UTC](https://discourse.julialang.org/t/would-matrix-multiplication-benefit-if-julia-allowed-for-row-major-arrays-as-well/15214/1 "2018-09-20T06:23:04Z")

</div>

Just a random thought. Consider multiplication of three matrices: `A * (B * C)`

If `A` is column-major, would the execution times of the outer product be substantially smaller (if the size of the product `B * C` and matrix `A` exceed CPU cache size) if Julia would optimize the product `(B * C)` as a row-major temporary matrix?

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [September 20, 2018, 11:37am UTC](https://discourse.julialang.org/t/would-matrix-multiplication-benefit-if-julia-allowed-for-row-major-arrays-as-well/15214/2 "2018-09-20T11:37:16Z")

</div>

No. The blocking performed by an optimized BLAS implementation mostly eliminates the difference between row-major and column-major memory layouts. You can easily test this for yourself, because a transposed column-major array is equivalent to a row-major array, and so doing `A*B'` in Julia is equivalent to column-major × row-major. (Julia evaluates `A*B'` by calling a BLAS routine that operates in-place on `A` and `B`.)

```julia
julia> using BenchmarkTools

julia> A = rand(1000,1000); B = copy(A);

julia> f(a,b) = a*b
f (generic function with 1 method)

julia> g(a,b) = a'*b
g (generic function with 1 method)

julia> h(a,b) = a*b'
h (generic function with 1 method)

julia> @btime f($A,$B) evals=1;
  13.416 ms (2 allocations: 7.63 MiB)

julia> @btime g($A,$B) evals=1;
  13.364 ms (2 allocations: 7.63 MiB)

julia> @btime h($A,$B) evals=1;
  13.560 ms (2 allocations: 7.63 MiB)

```

The timing differences here are less than 2%, which is probably within the noise.

See also [Row Major Arrays · Issue #5932 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/5932)

Of course, there are other reasons to support row-major formats, mainly to pass data to/from external libraries without making copies, but this can be done by add-on packages. (e.g. PyCall already supports this to provide copy-free views of row-major NumPy arrays.)
