Rcpp - 在 for 和 while 循环中加速随机正常绘制

Posted

技术标签:

【中文标题】Rcpp - 在 for 和 while 循环中加速随机正常绘制【英文标题】:Rcpp - speeding up random normal draws within for and while loop 【发布时间】:2018-03-23 17:13:17 【问题描述】:

我是 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 函数会以某种方式使函数更快,但我不知道如何。

感谢您的任何建议!

编辑: 只是为了完整起见,这是我根据 Dirk 的非常有用的建议用 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 倍以上!

【问题讨论】:

【参考方案1】:

您可以使用 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++ 级别的其他包中使用。它只是您以通常方式提取的标题。

【讨论】:

以上是关于Rcpp - 在 for 和 while 循环中加速随机正常绘制的主要内容,如果未能解决你的问题,请参考以下文章

rowsum 的 Rcpp 等效项 [关闭]

js中for循环和while循环在使用的时候有何区别?

js中for循环和while循环在使用的时候有何区别?

Python里for和while的区别(74)

while循环和for循环

while循环和for循环