我有一个非常简单的问题,是使用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
顶部使用sum而底部使用矩阵乘法。任何提示,建议都欢迎!谢谢!
答案 0 :(得分:5)
您可能对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
所以在我的(慢)笔记本电脑上,它们或多或少相同。
答案 1 :(得分:1)
尝试一个简单的事情就是使用更大的矢量。
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
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的向量,使比较更加公平。