내가 나서서 Rcpp
이 구현하고 R
기능에 일부 조정을했다 :
require(Rcpp);require(microbenchmark);require(ggplot2);
limitstretchR <- function(upperlimit,original) {
remainder <- 0
out <- vector(length=length(original))
for(i in 1:length(original)){
if(original[i] >= upperlimit){
out[i] <- upperlimit
} else {
out[i] <- min(remainder,upperlimit)
}
remainder <- remainder + original[i] - out[i]
}
out
}
Rcpp
기능 :
cppFunction('
NumericVector limitstretchC(double upperlimit, NumericVector original) {
int n = original.size();
double remainder = 0.0;
NumericVector out(n);
for(int i = 0; i < n; ++i) {
if (original[i] >= upperlimit) {
out[i] = upperlimit;
} else {
out[i] = std::min<double>(remainder,upperlimit);
}
remainder = remainder + original[i] - out[i];
}
return out;
}
')
테스트 그들 :
x <- c(0,2101,3389,3200,1640,0,0,0,0,0,0,0)
original <- rep(x,20000)
upperlimit <- 2000
system.time(limitstretchR(upperlimit,original))
system.time(limitstretchC(upperlimit,original))
그 80.655와 0.001 초를 되찾았다. 광적으로. 네이티브 R
은 이것에 상당히 나쁜 것입니다. 그러나 microbenchmark
(작은 벡터 사용)을 실행하고 혼란스러운 결과를 얻었습니다.
res <- microbenchmark(list=
list(limitstretchR=limitstretchR(upperlimit,rep(x,10000)),
limitstretchC=limitstretchC(upperlimit,rep(x,10000))),
times=110,
control=list(order="random",warmup=10))
print(qplot(y=time, data=res, colour=expr) + scale_y_log10())
boxplot(res)
print(res)
실행하려면 두 기능 모두 거의 동일한 결과가 나타납니다. 이것은 처음으로 microbenchmark
, 어떤 팁을 사용하고 있습니까?
'upperlimit'은 절대 변경되지 않으므로,'dat $ x> = upperlimit'를 먼저 계산하면 성능이 크게 향상됩니다. –
일반적인 조언 : data.frame 하위 설정이 느립니다. 루프의 벡터를 사용하여 결과를 마지막에 data.frame에 결합하십시오. – Roland