求和或矩阵乘法更快吗?
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 的向量,使比较更加公平。
我有一个非常简单的问题,使用 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 的向量,使比较更加公平。