隨着德克的響應here:
有固定不使用顯式循環 在C++代碼的代碼的方式?
我不這麼認爲。該代碼目前有這種硬連線:< ...>如此 ,直到我們中的一個人有足夠的時間來延長這個(並測試它)將有 做你的最後的循環。
下面是我實現的「矢量化」代碼:
library(Rcpp)
cppFunction("NumericVector cpprbinom(int n, double size, NumericVector prob) {
NumericVector v(n);
for (int i=0; i<n; i++) {v[i] = as<double>(rbinom(1, size, prob[i]));}
return(v); }")
r <- runif(1e6)
all.equal({set.seed(42); rbinom(length(r), 1, r)},
{set.seed(42); cpprbinom(length(r), 1, r)})
#TRUE
但問題是,(再次引用德克),
而且我認爲上花費了很大的力氣才這你檢查 你是否可能比R函數更好。 R函數是用C代碼矢量化的,並且除非要在其他C++函數中使用隨機變量 ,否則您不太可能通過使用Rcpp使事情變得更加快速 。
而且它實際上是比較慢(我的機器上三次),所以至少這種天真的實現礦山不會幫助:
library(microbenchmark)
microbenchmark(rbinom(length(r), 1, r), cpprbinom(length(r), 1, r))
Unit: milliseconds
expr min lq mean median uq max neval
rbinom(length(r), 1, r) 55.50856 56.09292 56.49456 56.45297 56.65897 59.42524 100
cpprbinom(length(r), 1, r) 117.63761 153.37599 154.94164 154.29623 155.37247 225.56535 100
編輯:根據以下羅曼的評論,這裏是一個高級版本,這是更快!
cppFunction(plugins=c("cpp11"), "NumericVector cpprbinom2(int n, double size, NumericVector prob) {
NumericVector v = no_init(n);
std::transform(prob.begin(), prob.end(), v.begin(), [=](double p){ return R::rbinom(size, p); });
return(v);}")
r <- runif(1e6)
all.equal({set.seed(42); rbinom(length(r), 1, r)},
{set.seed(42); cpprbinom(length(r), 1, r)},
{set.seed(42); cpprbinom2(length(r), 1, r)})
#TRUE
microbenchmark(rbinom(length(r), 1, r), cpprbinom(length(r), 1, r), cpprbinom2(length(r), 1, r))
Unit: milliseconds
expr min lq mean median uq max neval
rbinom(length(r), 1, r) 55.26412 56.00314 56.57814 56.28616 56.59561 60.01861 100
cpprbinom(length(r), 1, r) 113.72513 115.94758 122.81545 117.24708 119.95134 168.47246 100
cpprbinom2(length(r), 1, r) 36.67589 37.12182 38.95318 37.37436 37.97719 84.73516 100
選中此項:http://lists.r-forge.r-project.org/pipermail/rcpp-devel/2012-October/004477.html – tonytonov 2015-04-03 11:07:58