gpt4 book ai didi

r - do.call 比 R 中的普通调用慢 20%?

转载 作者:行者123 更新时间:2023-12-04 22:47:39 24 4
gpt4 key购买 nike

我不确定我是否使用 do.call正确的方式:

test <- function(test) {
string <- deparse(substitute(test))
start <- regexpr("\\(", string)
end <- regexpr(")", string) - 1
distribution <- substr(string, 0, start-1)
string.arguments <- substr(string, start+1, end)
v <- read.table(text=unlist(strsplit(string.arguments, ",")))
list.arguments <- lapply(t(v), function(x) x)

for (i in 1:1000000) {
do.call(distribution, list.arguments)
}
}

这里的目标是能够发送分布,例如 rnormrgamma , 后跟函数的参数,而不是求值函数。

这是使用 do.call 和简单调用函数的比较:
> system.time(test(rnorm(100, 1, 10))) 
user system elapsed
17.772 0.000 17.820
> system.time(for(i in 1:1000000) { rnorm(100,0,1)} )
user system elapsed
13.940 0.004 14.015

问题是双重的:
  • do.call 真的需要多花 20% 的时间吗?
  • 这是接受不同分布和参数的正确方法吗?
  • 最佳答案

    do.call总是比直接调用函数要慢,因为它必须通过你的参数并在调用之前找到函数。它变慢的程度取决于它有多少额外的计算来分摊这个开销。

    > system.time(for(i in 1:1e6) do.call(rnorm, list(100)))
    user system elapsed
    13.55 0.00 13.58
    > system.time(for(i in 1:1e6) rnorm(100))
    user system elapsed
    11.40 0.00 11.42

    然而:
    > system.time(for(i in 1:1e2) do.call(rnorm, list(1e6)))
    user system elapsed
    9.14 0.00 9.15
    > system.time(for(i in 1:1e2) rnorm(1e6))
    user system elapsed
    9.14 0.00 9.14

    此外,您的某些速度变慢是由于您的正则表达式和其他字符串操作与速度无关 do.call本质上是。虽然速度很快,因为它在很小的输入上运行,但它仍然不必要地复杂。为什么不这样做:
    test <- function(distrib, ..., N=1e6)
    lapply(seq(N), function(x) distrib(...))

    test(rnorm, 100, 1, 10)

    或这个:
    test <- function(call, N=1e6)
    {
    call <- substitute(call)
    lapply(seq(N), function(...) eval.parent(call))
    }

    test(rnorm(100, 1, 10))

    关于r - do.call 比 R 中的普通调用慢 20%?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17629499/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com