求和或矩阵乘法更快吗?

Is sum or matrix multiplication faster?

我有一个非常简单的问题,使用 sum 或矩阵乘法对大向量求和是否更快?更准确地说,这是我试图加速的问题示例:

d <- 1000
X <- matrix(rnorm(d^2), nrow = d)
y <- rnorm(d)

## Solution 1
sum(X%*%y)
## Solution 2
rep(1, d)%*%(X%*%y)

我已经尝试用 system.time() 测试两者,但时间相互跳跃,我无法修复它。时代非常相似,所以这个问题已经从实用变成了好奇。也许他们是完全相同的时间(似乎不太可能)。

这是我为测试它而编写的函数:

testSum <- function(d, its){
  X <- matrix(rnorm(d^2), nrow=d)
  y <- rnorm(d)

  store <- matrix(NA, nrow = its, ncol = 3)
  store2 <- matrix(NA, nrow = its, ncol = 3)

  for(i in 1:its) store[i, ] <- system.time(sum(X%*%y))[1:3]
  for(i in 1:its) store2[i, ] <- system.time(rep(1, d)%*%(X%*%y))[1:3]

  return(list(sumF = mean(store[, 1]),
              MM = mean(store2[, 1])))
}

testSum(1000, 100)

输出总是像这样:

$sumF
[1] 0.01021

$MM
[1] 0.01028

其中顶部使用求和,底部使用矩阵乘法。欢迎任何提示,建议!谢谢!

您可能对 microbenchmark 包感兴趣,这是一种对小函数进行多次计时的简单方法:

microbenchmark::microbenchmark(sum(X%*%y),rep(1, d)%*%(X%*%y))

给我:

Unit: milliseconds
                    expr      min       lq     mean   median       uq      max neval
            sum(X %*% y) 10.01472 10.52420 14.25944 11.11969 13.67134 74.26345   100
 rep(1, d) %*% (X %*% y) 10.13382 10.55444 12.99910 10.87629 12.95769 50.38268   100

所以在我的(慢)笔记本电脑上,它们或多或少是一样的。

一个简单的尝试是使用更大的矢量。

用一百万。

library(microbenchmark)

A <- rnorm(1000000)
B <- rep(1, 1000000)

system.time(sum(A))
user  system elapsed
0.012   0.000   0.01

system.time(B %*% A)
user  system elapsed
0.044   0.000   0.04

microbenchmark(sum(A), B%*%A)
Unit: microseconds
   expr      min       lq     mean   median       uq      max neval
 sum(A)  899.735  953.361 1021.005 1021.415 1081.348 1885.857   100
B %*% A 2846.589 2946.579 3063.001 2993.341 3132.779 4498.773   100

使用1000万

library(microbenchmark)

A <- rnorm(10000000)
B <- rep(1, 10000000)

system.time(sum(A))
user  system elapsed
0.012   0.000   0.011

system.time(B %*% A)
user  system elapsed
0.044   0.000   0.044

microbenchmark(sum(A), B%*%A)
Unit: milliseconds
   expr       min        lq      mean    median       uq      max neval
 sum(A)  8.993579  9.294605  9.975156  9.729226 10.22477 14.29411   100
B %*% A 32.716323 33.818031 35.586381 35.966695 36.86165 41.13194   100

在我的机器上,求和速度快了约 4 倍。

注意:我预先计算了向量,而不是将向量与矩阵相乘以获得向量。还预先计算了 1 的向量,使比较更加公平。