在RI中有以下示例模块,它重复一个for循环n时间:
function(n){
#inputs - n - number of results required
#reserve n spaces for results
r_num_successes <- 1:n
#start looping n times
for(i in 1:n){
#set first uniform "random" deviate equal to 0.05 and number of successes to 0
current_unif <- 0.05
num_successes <- 0
#start while loop that updates current_unif - it runs as long as
#current_unif is less than 0.95, increments num_successes each loop
while(current_unif < 0.95){
#set current_unif to a uniform random deviate between the
#existing current_unif and 1
current_unif <- runif(1,current_unif)
num_successes <- num_successes + 1
}
#set the i-th element of the results vector to that final num_successes
#generated by the while loop
r_num_successes[i] <- num_successes
}
#output the mean of all the successes
return(mean(r_num_successes))
}
Run Code Online (Sandbox Code Playgroud)
当n变大时,这开始慢慢磨.有优化它的好方法吗?
Jos*_*ich 10
没有什么可以用纯R来显着提高速度.字节编译会给你一个小的改进,但你需要转移到编译代码以获得任何显着的速度增益.
更新:这是一个Rcpp解决方案,仅适用于Dirk :)
> nCode <- '
+ int N = as<int>(n);
+ std::vector<double> rns;
+
+ RNGScope scope; // Initialize Random number generator
+
+ for(int i=0; i<N; i++) {
+ double current_unif = 0.05;
+ double num_successes = 0;
+ while(current_unif < 0.95) {
+ current_unif = ::Rf_runif(current_unif, 1.0);
+ num_successes++;
+ }
+ rns.push_back(num_successes);
+ }
+
+ double mean = std::accumulate(rns.begin(), rns.end(), 0.0) / rns.size();
+ return wrap(mean); // Return to R
+ '
>
> library(inline)
> nFunRcpp <- cxxfunction(signature(n="int"), nCode, plugin="Rcpp")
> library(compiler)
> nFunCmp <- cmpfun(nFun)
> system.time(nFun(1e5))
user system elapsed
3.100 0.000 3.098
> system.time(nFunCmp(1e5))
user system elapsed
2.120 0.000 2.114
> system.time(nFunRcpp(1e5))
user system elapsed
0.010 0.000 0.016
Run Code Online (Sandbox Code Playgroud)