我正在试图理解使用RcppArmadillo编写的函数和使用Armadillo库编写的独立C++程序之间性能差异。例如,考虑以下简单函数,它使用传统教科书公式计算线性模型的系数。
这段代码在一个
现在考虑一个非常相似的C++函数,然后使用
在这里,
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
using namespace arma;
// [[Rcpp::export]]
void simpleLm(NumericMatrix Xr, NumericMatrix yr) {
int n = Xr.nrow(), k = Xr.ncol();
mat X(Xr.begin(), n, k, false);
colvec y(yr.begin(), yr.nrow(), false);
colvec coef = inv(X.t()*X)*X.t()*y;
}
这段代码在一个
1000000x100
的矩阵 X
上运行大约需要6秒钟。代码中的一些时间测量(未显示)表明所有的时间都花费在了 coef
计算上。X <- matrix(rnorm(1000000*100), ncol=100)
y <- matrix(rep(1, 1000000))
system.time(simpleLm(X,y))
user system elapsed
6.028 0.009 6.040
现在考虑一个非常相似的C++函数,然后使用
g++
编译。#include <iostream>
#include <armadillo>
#include <chrono>
#include <cstdlib>
using namespace std;
using namespace arma;
int main(int argc, char **argv) {
int n = 1000000;
mat X = randu<mat>(n,100);
vec y = ones<vec>(n);
chrono::steady_clock::time_point start = chrono::steady_clock::now();
colvec coef = inv(X.t()*X)*X.t()*y;
chrono::steady_clock::time_point end = chrono::steady_clock::now();
chrono::duration<double, milli> diff = end - start;
cout << diff.count() << endl;
return 0;
}
在这里,
coef
变量的计算只需要大约 0.5 秒钟,或者说只有使用 RcppArmadillo 时所需时间的 1/12。我使用的是 Mac OS X 10.9.2,R 3.1.0,Rcpp 0.11.1 和 RcppArmadillo 0.4.200.0。我使用 sourceCpp 函数编译了 Rcpp 示例。独立的 C++ 示例使用 Armadillo 4.200.0,并且我还使用 Homebrew 安装了 Mac 的 Fortran 编译器(brew install gfortran
)。
sourceCpp
中尝试使用verbose=TRUE
)。你应该确保编译独立的C++文件时也使用相同的优化级别。 - Kevin Ushey