rcpp编程效率
Rcpp programming efficiency
我是 Rcpp 的初学者。目前我写了一个Rcpp代码,应用于两个3维数组:Array1
和Array2
。假设 Array1
的维度为 (1000, 100, 40),Array2
的维度为 (1000, 96, 40)。
我想执行 wilcox.test
使用:
wilcox.test(Array1[i, j,], Array2[i,,])
在R中,我写了嵌套的for
循环,大约半小时就完成了计算。
然后,我把它写进了Rcpp。 Rcpp 中的计算需要一个小时才能达到相同的结果。我认为它应该更快,因为它是用 C++ 语言编写的。我想我的编码风格是低效率的原因。
以下是我的Rcpp代码,请问您能帮我看看我应该做哪些改进吗?我很感激!
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector Cal(NumericVector Array1,NumericVector Array2,Function wilc) {
NumericVector vecArray1(Array1);
IntegerVector arrayDims1 = vecArray1.attr("dim");
NumericVector vecArray2(Array2);
IntegerVector arrayDims2 = vecArray2.attr("dim");
arma::cube cubeArray1(vecArray1.begin(), arrayDims1[0], arrayDims1[1], arrayDims1[2], false);
arma::cube cubeArray2(vecArray2.begin(), arrayDims2[0], arrayDims2[1], arrayDims2[2], false);
arma::mat STORE=arma::mat(arrayDims1[0], arrayDims1[1]);
for(int i=0;i<arrayDims1[1];i++)
{
for(int j=0;j<arrayDims1[0];j++){
arma::vec v_cl=cubeArray1.subcube(arma::span(j),arma::span(i),arma::span::all);
//arma::mat tem=cubeArray2.subcube(arma::span(j),arma::span::all,arma::span::all);
//arma::vec v_ct=arma::vectorise(tem);
arma::vec v_ct=arma::vectorise(cubeArray2.subcube(arma::span(j),arma::span::all,arma::span::all));
Rcpp::List resu=wilc(v_cl,v_ct);
STORE(j,i)=resu[2];
}
}
return(Rcpp::wrap(STORE));
}
函数 wilc
将从 R.
变为 wilcox.test
下面是我的R实现上述思路的部分代码,其中CELLS
和CTRLS
是[=37=中的两个3D数组]R.
for(i in 1:ncol(CELLS)) {
if(T){ print(i) }
for (j in 1:dim(CELLS)[1]) {
wtest = wilcox.test(CELLS[j,i,], CTRLS[j,,])
TSTAT_clcl[j,i] = wtest$p.value
}
}
Then, I wrote it into Rcpp. The calculation within Rcpp took an hour to achieve the same results. I thought it should be faster since it is written in C++ language.
所需的免责声明:
在 C++ 中嵌入 R 代码并期望加速是傻瓜游戏。您需要用 C++ 完全重写 wilcox.test
而不是调用 R。否则,您将失去获得的任何加速优势。
特别是,我写了一篇 post 来说明这个关于在 R 中使用 diff
函数的难题。在 post 中,我详细比较了 pure C++ 实现,C++ 实现使用例程中的 R 函数,以及纯 R 实现。窃取 microbenchmark
说明了上述问题。
expr min lq mean median uq max neval
arma_fun 26.117 27.318 37.54248 28.218 29.869 751.087 100
r_fun 127.883 134.187 212.81091 138.390 151.148 1012.856 100
rcpp_fun 250.663 265.972 356.10870 274.228 293.590 1430.426 100
因此,pure C++ 实现的加速最大。
因此,要点是需要将 wilcox.test
R 例程代码转换为纯 C++ 实现删除 运行 时间。否则用C++写代码是没有意义的,因为C++组件必须停止并等待结果从 R 开始,然后继续。这传统上有 很多 的开销以确保数据得到很好的保护。
我是 Rcpp 的初学者。目前我写了一个Rcpp代码,应用于两个3维数组:Array1
和Array2
。假设 Array1
的维度为 (1000, 100, 40),Array2
的维度为 (1000, 96, 40)。
我想执行 wilcox.test
使用:
wilcox.test(Array1[i, j,], Array2[i,,])
在R中,我写了嵌套的for
循环,大约半小时就完成了计算。
然后,我把它写进了Rcpp。 Rcpp 中的计算需要一个小时才能达到相同的结果。我认为它应该更快,因为它是用 C++ 语言编写的。我想我的编码风格是低效率的原因。
以下是我的Rcpp代码,请问您能帮我看看我应该做哪些改进吗?我很感激!
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector Cal(NumericVector Array1,NumericVector Array2,Function wilc) {
NumericVector vecArray1(Array1);
IntegerVector arrayDims1 = vecArray1.attr("dim");
NumericVector vecArray2(Array2);
IntegerVector arrayDims2 = vecArray2.attr("dim");
arma::cube cubeArray1(vecArray1.begin(), arrayDims1[0], arrayDims1[1], arrayDims1[2], false);
arma::cube cubeArray2(vecArray2.begin(), arrayDims2[0], arrayDims2[1], arrayDims2[2], false);
arma::mat STORE=arma::mat(arrayDims1[0], arrayDims1[1]);
for(int i=0;i<arrayDims1[1];i++)
{
for(int j=0;j<arrayDims1[0];j++){
arma::vec v_cl=cubeArray1.subcube(arma::span(j),arma::span(i),arma::span::all);
//arma::mat tem=cubeArray2.subcube(arma::span(j),arma::span::all,arma::span::all);
//arma::vec v_ct=arma::vectorise(tem);
arma::vec v_ct=arma::vectorise(cubeArray2.subcube(arma::span(j),arma::span::all,arma::span::all));
Rcpp::List resu=wilc(v_cl,v_ct);
STORE(j,i)=resu[2];
}
}
return(Rcpp::wrap(STORE));
}
函数 wilc
将从 R.
wilcox.test
下面是我的R实现上述思路的部分代码,其中CELLS
和CTRLS
是[=37=中的两个3D数组]R.
for(i in 1:ncol(CELLS)) {
if(T){ print(i) }
for (j in 1:dim(CELLS)[1]) {
wtest = wilcox.test(CELLS[j,i,], CTRLS[j,,])
TSTAT_clcl[j,i] = wtest$p.value
}
}
Then, I wrote it into Rcpp. The calculation within Rcpp took an hour to achieve the same results. I thought it should be faster since it is written in C++ language.
所需的免责声明:
在 C++ 中嵌入 R 代码并期望加速是傻瓜游戏。您需要用 C++ 完全重写 wilcox.test
而不是调用 R。否则,您将失去获得的任何加速优势。
特别是,我写了一篇 post 来说明这个关于在 R 中使用 diff
函数的难题。在 post 中,我详细比较了 pure C++ 实现,C++ 实现使用例程中的 R 函数,以及纯 R 实现。窃取 microbenchmark
说明了上述问题。
expr min lq mean median uq max neval
arma_fun 26.117 27.318 37.54248 28.218 29.869 751.087 100
r_fun 127.883 134.187 212.81091 138.390 151.148 1012.856 100
rcpp_fun 250.663 265.972 356.10870 274.228 293.590 1430.426 100
因此,pure C++ 实现的加速最大。
因此,要点是需要将 wilcox.test
R 例程代码转换为纯 C++ 实现删除 运行 时间。否则用C++写代码是没有意义的,因为C++组件必须停止并等待结果从 R 开始,然后继续。这传统上有 很多 的开销以确保数据得到很好的保护。