I noticed that evaluating matrix operations in quadratic form from right to left is significantly faster than left to right in R, depending on how the parentheses are placed. Obviously they both perform the same amount of calculation. I am wondering why this is the case. Does this have anything to do with memory allocation?
# A: 5000 * 5000
# B: 5000 * 2
A = matrix(runif(5000 * 5000), nrow = 5000)
B = matrix(rbinom(5000 * 2, size = 2, prob = 0.3), nrow = 5000)
microbenchmark((t(B) %*% A) %*% B, t(B) %*% (A %*% B), times = 100)
Here is the session info:
R version 4.2.0 (2022-04-22)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Big Sur 11.4
Matrix products: default
LAPACK: /Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/lib/libRlapack.dylib
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] Rcpp_1.0.9 microbenchmark_1.4.9
loaded via a namespace (and not attached):
[1] compiler_4.2.0 fastmap_1.1.0 cli_3.3.0 htmltools_0.5.3 tools_4.2.0
[6] RcppArmadillo_0.11.2.4.0 rstudioapi_0.13 yaml_2.3.5 rmarkdown_2.14 knitr_1.39
[11] xfun_0.31 digest_0.6.29 rlang_1.0.4 evaluate_0.15
EDIT: A simplified version of the matrix multiplication which displays the same error.
k <- 5000L; m <- n <- 2L;
A <- matrix(rnorm(k * k), k, k);
B <- matrix(rnorm(k * n), k, n);
tB <- t(B);
microbenchmark::microbenchmark(tB %*% A, A %*% B, times = 100)