使累积和更快 [英] Make cumulative sum faster
问题描述
我正在尝试对矩阵的每一列求累计和.这是我在 R 中的代码:
I'm trying to take cumulative sums for each column of a matrix. Here's my code in R:
testMatrix = matrix(1:65536, ncol=256);
microbenchmark(apply(testMatrix, 2, cumsum), times=100L);
Unit: milliseconds
expr min lq mean median uq max neval
apply(testMatrix, 2, cumsum) 1.599051 1.766112 2.329932 2.15326 2.221538 93.84911 10000
我使用 Rcpp 进行比较:
I used Rcpp for comparison:
cppFunction('NumericMatrix apply_cumsum_col(NumericMatrix m) {
for (int j = 0; j < m.ncol(); ++j) {
for (int i = 1; i < m.nrow(); ++i) {
m(i, j) += m(i - 1, j);
}
}
return m;
}');
microbenchmark(apply_cumsum_col(testMatrix), times=10000L);
Unit: microseconds
expr min lq mean median uq max neval
apply_cumsum_col(testMatrix) 205.833 257.719 309.9949 265.986 276.534 96398.93 10000
所以 C++ 代码的速度是原来的 7.5 倍.在纯 R 中是否有可能比 apply(testMatrix, 2, cumsum)
做得更好?感觉就像我无缘无故地有一个数量级的开销.
So the C++ code is 7.5 times as fast. Is it possible to do better than apply(testMatrix, 2, cumsum)
in pure R? It feels like I have an order of magnitude overhead for no reason.
推荐答案
使用字节编译的 for 循环比在我的系统上调用 apply
稍快.我预计它会更快,因为它比 apply
做的工作更少.不出所料,R 循环仍然比您编写的简单 C++ 函数慢.
Using a byte-compiled for loop is slightly faster than the apply
call on my system. I expected it to be faster because it does less work than apply
. As expected, the R loop is still slower than the simple C++ function you wrote.
colCumsum <- compiler::cmpfun(function(x) {
for (i in 1:ncol(x))
x[,i] <- cumsum(x[,i])
x
})
testMatrix <- matrix(1:65536, ncol=256)
m <- testMatrix
require(microbenchmark)
microbenchmark(colCumsum(m), apply_cumsum_col(m), apply(m, 2, cumsum), times=100L)
# Unit: microseconds
# expr min lq median uq max neval
# matrixCumsum(m) 1478.671 1540.5945 1586.1185 2199.9530 37377.114 100
# apply_cumsum_col(m) 178.214 192.4375 204.3905 234.8245 1616.030 100
# apply(m, 2, cumsum) 1879.850 1940.1615 1991.3125 2745.8975 4346.802 100
all.equal(colCumsum(m), apply(m, 2, cumsum))
# [1] TRUE
这篇关于使累积和更快的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!