Rcpp - 在 for 和 while 循环中加速随机正常绘制
Rcpp - speeding up random normal draws within for and while loop
我是 Rcpp 的新手,正在探索它的应用程序。特别是,我试图加快以下功能,部分建立在 previous answer:
code = 'NumericVector RcppFun(int N){
NumericVector out(N);
for (int i = 0; i < N; ++i) {
double V = 0;
while( V > -1e04 && V < 1e04 ) {
V += R::rnorm(10, 100);
}
out[i] = V;
}
return out;
}'
cppFunction(code)
system.time(RcppFun(1e05))
代码比对应的 R 代码快得多,但在我的计算机上 运行 仍然需要几秒钟。鉴于我需要多次调用这个函数,我想知道是否可以进一步提高它的性能。
我在想修改 while 循环中的逻辑语句或更改 RNG 函数会以某种方式使函数更快,但我不知道如何做。
感谢您的任何建议!
编辑: 为了完整起见,这是我根据德克非常有用的建议用 C++ 编写的代码:
#include <Rcpp.h>
// [[Rcpp::depends(RcppZiggurat)]]
#include <Ziggurat.h>
using namespace Rcpp;
static Ziggurat::Ziggurat::Ziggurat zigg;
// [[Rcpp::export]]
NumericVector ZiggFun(int N){
NumericVector out(N);
for (int i = 0; i < N; ++i) {
double V = 0;
while( V > -1e04 && V < 1e04 ) {
V += 10 + zigg.norm()*100;
}
out[i] = V;
}
return out;
}
根据 rbenchmark::benchmark 估计,新代码现在快了 7 倍多!
您可以使用 RcppZiggurat 来加快 RNG 抽取速度——我在包中进行了时序比较:
R> library(RcppZiggurat)
R> library(microbenchmark)
R> microbenchmark(rnorm(1e5), zrnorm(1e5))
Unit: microseconds
expr min lq mean median uq max neval cld
rnorm(1e+05) 6148.781 6169.917 6537.31 6190.073 6923.357 10166.96 100 b
zrnorm(1e+05) 719.458 887.554 1016.03 901.182 939.652 2880.47 100 a
R>
这个 RNG 也可以在 C++ 级别的其他包中使用。它只是一个 header 你以通常的方式拉。
我是 Rcpp 的新手,正在探索它的应用程序。特别是,我试图加快以下功能,部分建立在 previous answer:
code = 'NumericVector RcppFun(int N){
NumericVector out(N);
for (int i = 0; i < N; ++i) {
double V = 0;
while( V > -1e04 && V < 1e04 ) {
V += R::rnorm(10, 100);
}
out[i] = V;
}
return out;
}'
cppFunction(code)
system.time(RcppFun(1e05))
代码比对应的 R 代码快得多,但在我的计算机上 运行 仍然需要几秒钟。鉴于我需要多次调用这个函数,我想知道是否可以进一步提高它的性能。
我在想修改 while 循环中的逻辑语句或更改 RNG 函数会以某种方式使函数更快,但我不知道如何做。
感谢您的任何建议!
编辑: 为了完整起见,这是我根据德克非常有用的建议用 C++ 编写的代码:
#include <Rcpp.h>
// [[Rcpp::depends(RcppZiggurat)]]
#include <Ziggurat.h>
using namespace Rcpp;
static Ziggurat::Ziggurat::Ziggurat zigg;
// [[Rcpp::export]]
NumericVector ZiggFun(int N){
NumericVector out(N);
for (int i = 0; i < N; ++i) {
double V = 0;
while( V > -1e04 && V < 1e04 ) {
V += 10 + zigg.norm()*100;
}
out[i] = V;
}
return out;
}
根据 rbenchmark::benchmark 估计,新代码现在快了 7 倍多!
您可以使用 RcppZiggurat 来加快 RNG 抽取速度——我在包中进行了时序比较:
R> library(RcppZiggurat)
R> library(microbenchmark)
R> microbenchmark(rnorm(1e5), zrnorm(1e5))
Unit: microseconds
expr min lq mean median uq max neval cld
rnorm(1e+05) 6148.781 6169.917 6537.31 6190.073 6923.357 10166.96 100 b
zrnorm(1e+05) 719.458 887.554 1016.03 901.182 939.652 2880.47 100 a
R>
这个 RNG 也可以在 C++ 级别的其他包中使用。它只是一个 header 你以通常的方式拉。