Кросспрод медленнее, чем% *%, почему? - PullRequest
1 голос
/ 06 ноября 2019

В различных попытках сократить время вычисления алгоритма, который я кодировал в последние несколько дней, я хотел проверить эффективное улучшение, полученное с помощью crossprod на %*%. Я неожиданно заметил, что при использовании %*% мой алгоритм будет работать быстрее.

Поэтому я решил сравнить две подпрограммы, используя microbenchmark() (а также system.time()) на общих матрицах, и я получил следующеерезультаты:

M <- 1000
K <- 100
A <- matrix(rnorm(M*K, 10, 1), ncol = M)
b <- rnorm(K, 10, 1)
B <- matrix(rnorm(M*K, 10, 1), ncol = M)

microbenchmark(crossprod(A, A), t(A)%*%A, times = 1000, unit="ms")
Unit: milliseconds
            expr       min        lq     mean    median       uq      max neval cld
 crossprod(A, A) 112.58885 121.05406 149.8290 129.31873 147.6489 358.3164  1000   b
      t(A) %*% A  76.77698  81.68934 108.0526  89.50015 105.9617 304.7395  1000  a 

microbenchmark(crossprod(A), t(A)%*%A, times = 1000, unit="ms")
Unit: milliseconds
         expr      min       lq     mean   median       uq      max neval cld
 crossprod(A) 58.26374 61.56330 69.35781 64.65561 71.42403 314.9268  1000  a 
   t(A) %*% A 76.97771 81.80069 92.21863 85.75894 93.50332 273.5133  1000   b

microbenchmark(crossprod(A, B), t(A)%*%B, times = 1000, unit="ms")
Unit: milliseconds
            expr       min       lq      mean    median        uq      max neval cld
 crossprod(A, B) 109.27471 111.6751 118.00118 112.97533 117.55815 284.6910  1000   b
      t(A) %*% B  74.36276  77.0441  83.33582  77.89172  82.58609 258.3154  1000  a

microbenchmark(crossprod(A, b), t(A)%*%b, times = 1000, unit="ms")
Unit: milliseconds
            expr      min        lq      mean    median       uq       max neval cld
 crossprod(A, b) 0.149644 0.1553795 0.1884534 0.1577500 0.167333  6.737466  1000  a 
      t(A) %*% b 0.338180 0.6239705 0.8052485 0.6423505 0.678017 13.011479  1000   b

microbenchmark(crossprod(b, d), t(b)%*%d, times = 1000, unit="ms")
Unit: milliseconds
            expr      min        lq        mean   median        uq      max neval cld
 crossprod(b, d) 0.000814 0.0009130 0.001153643 0.000973 0.0010740 0.018912  1000  a 
      t(b) %*% d 0.002547 0.0029275 0.003554290 0.003087 0.0033005 0.057184  1000   b

microbenchmark(crossprod(b), t(b)%*%b, times = 1000, unit="ms")
Unit: milliseconds
         expr      min       lq        mean   median       uq      max neval cld
 crossprod(b) 0.000758 0.000801 0.000866091 0.000848 0.000883 0.004277  1000  a 
   t(b) %*% b 0.002546 0.002686 0.002872259 0.002785 0.002898 0.033779  1000   b

По-видимому, по крайней мере на моем компьютере crossprod работает быстрее только при работе с векторами или при взятии квадрата матрицы без указания аргумента y.

Я знаю, чтотеоретически, crossprod должен быть вообще быстрее, так как это возможно?

sessionInfo()
R version 3.6.1 (2019-07-05)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Manjaro Linux

Matrix products: default
BLAS:   /usr/lib/libblas.so.3.8.0
LAPACK: /usr/lib/liblapack.so.3.8.0
...