Rcpp能代替R中的unif函数吗
Can Rcpp replace unif function in R?
我刚刚开始在R中使用Rcpp
包,我的学习灵感来自Hadley Wickham的高级R课程。
在R工作室中,我有以下.cpp文件。这个问题比较笼统,但这个例子有帮助。
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector runifC(int n, double min=0, double max=1) {
NumericVector out(n);
for(int i = 0; i < n; ++i) {
out[i] = min + ((double) rand() / (RAND_MAX)) * (max - min);
}
return out;
}
/*** R
library(microbenchmark)
microbenchmark(
'R unif-1' = runif(1),
'C++ unif-1' = runifC(1),
'R unif-100' = runif(100),
'C++ unif-100' = runifC(100),
'R unif-1000' = runif(1000),
'C++ unif-1000' = runifC(1000),
'R unif-100000' = runif(100000),
'C++ unif-100000' = runifC(100000)
)
*/
当我获取/保存文件时,它会向我显示性能输出。
Unit: nanoseconds
expr min lq mean median uq max neval
R unif-1 2061 2644.5 4000.71 3456.0 4297.0 15402 100
C++ unif-1 710 1190.0 1815.11 1685.0 2168.5 5776 100
R unif-100 4717 5566.5 6794.14 6563.0 7435.5 16600 100
C++ unif-100 1450 1997.5 2663.29 2591.5 3107.0 5307 100
R unif-1000 28210 29584.5 31310.54 30380.0 31599.0 52879 100
C++ unif-1000 8292 8951.0 10113.78 9462.5 10121.5 25099 100
R unif-100000 2642581 2975117.0 3104580.62 3030938.5 3119489.0 5435046 100
C++ unif-100000 699833 990924.0 1058855.49 1034430.5 1075078.0 1530351 100
我预计runif
将是一个非常优化的函数,但C++代码的运行效率要高得多。我在这里可能很天真,但如果性能上有这样的差异,那么为什么不用C++重写所有适用的R函数呢?
很明显,有很多可能的改进,我觉得我错过了一个巨大的原因,为什么不是所有的R函数都可以盲目地复制到C++中以提高性能。
edit:对于这个例子,已经表明rand()
的C++实现有一些缺陷。我最注意到的性能差距使用了CCD_ 4函数。其他功能的性能似乎没有那么激烈,所以我更改了问题的名称。
请不要使用rand()
。如果你提交的话,这样做也会让你的包裹从CRAN上掉下来。
如需警告,请参阅本C++参考页:
票据
对于所产生的随机序列的质量没有任何保证。在过去,rand()的一些实现在产生的序列的随机性、分布和周期方面存在严重缺陷(在一个众所周知的例子中,低阶比特在调用之间只是在1和0之间交替)。
如果您对备用随机数生成器和计时感兴趣,请访问Rcpp库。
通常,使用R提供的生成器,这些生成器具有良好的统计质量,并由Rcpp以标量和矢量形式("Rcpp Sugar")提供。
从R-3.1.1开始,runif
使用.External
接口,该接口复制其参数。Luke Tierney在66110版本中将其更改为使用R-devel中的.Call
接口。.Call
接口不复制其参数。Rcpp使用.Call
接口。
您的C++代码在R-devel下(使用.Call
接口)仍然更快。这可能是因为所使用的随机数生成器存在差异。此外,R的函数通常比您编写的任何专用代码都有更多的检查;而这些检查需要时间。
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 代码在main()中运行,但在函数中出现错误
- 内置函数可查看CPP中的成员变量
- 如何获取std::result_of函数的返回类型
- 如何在c++中为模板函数实例创建快捷方式
- Rcpp能代替R中的unif函数吗