Ben*_*ker 5
160 秒 (1e6/5e4 * 8) 对我来说一百万行听起来还不错(尽管您的实际功能可能比froot
您在这里使用的要慢得多?)。这可以简单地并行化,在不同的核心上运行单独的块(参见例如对这个问题的回答)。
你有多需要extendInt
?如果我制作一个uniroot()
只有核心功能、没有参数测试逻辑等的功能的破解版本,我可以将速度提高三倍。但是,如果您的目标功能比你在这里给出的例子;如果是这种情况,您应该专注于加速您的目标函数(我尝试froot
在 C++ 中通过重新编码您的代码Rcpp
,但在这种情况下它并没有真正帮助 - 该函数非常简单,函数调用开销需要大部分时间...)
为了便于基准测试,我只用了 5000 行来执行此操作:
n <- 5000
u <- -log(runif(n))
a <- 1/2
b <- 1
dt = data.table(u = u, a = a, b = b)
最小功能:
uu <- function(f, lower, upper, tol = 1e-8, maxiter =1000L, ...) {
f.lower <- f(lower, ...)
f.upper <- f(upper, ...)
val <- .External2(stats:::C_zeroin2, function(arg) f(arg, ...),
lower, upper, f.lower, f.upper, tol, as.integer(maxiter))
return(val[1])
}
检查我们是否得到相同的结果:
identical(uniroot(froot, u = 3.242, a=0.5, b=1, interval = c(0.01,100))$root,
uu(froot, u = 3.242, a=0.5, b=1, lower = 0.01, upper = 100))
## TRUE
基准测试包;将评估包装在函数中以实现紧凑性
library(rbenchmark)
f1 <- function() {
dt[, c := uniroot(froot_cpp, u=u, a=a, b=b, interval= c(0.01, 10), extendInt="yes")$root, by = u]
}
f2 <- function() {
dt[, c := uu(froot, u=u, a=a, b=b, lower = 0.01, upper = 100), by = u]
}
bb <- benchmark(f1(), f2(),
columns =c("test", "replications", "elapsed", "relative"))
结果:
test replications elapsed relative
1 f1() 100 34.616 3.074
2 f2() 100 11.261 1.000
更多推荐
更快,函数,方法,stats,uniroot
发布评论