gpt4 book ai didi

r - .Primitive 和 .Internal 的性能

转载 作者:行者123 更新时间:2023-12-03 22:32:49 24 4
gpt4 key购买 nike

我通过从流程中删除一个步骤来进行一些优化:

> library(microbenchmark)
> microbenchmark(paste0("this","and","that"))
Unit: microseconds
expr min lq mean median uq max neval
paste0("this", "and", "that") 2.026 2.027 3.50933 2.431 2.837 34.038 100

> microbenchmark(.Internal(paste0(list("this","and","that"),NULL)))
Unit: microseconds
expr min lq mean median uq max neval
.Internal(paste0(list("this", "and", "that"), NULL)) 1.216 1.621 2.77596 2.026 2.027 43.764 100
到现在为止还挺好。
但后来我注意到 list被定义为
function (...)  .Primitive("list")
我试图进一步“简化”
> microbenchmark(.Internal(paste0(.Primitive("list")("this","and","that"),NULL)))
Unit: microseconds
expr min lq mean median uq max neval
.Internal(paste0(.Primitive("list")("this", "and", "that"), NULL)) 3.241 3.242 4.66433 3.647 3.648 80.638 100
时间增加了!
我的猜测是处理字符串 "list"是问题的根源,并且在函数的实际调用中处理方式不同 list但如何?
免责声明:我知道这对可读性的伤害大于对性能的影响。这仅适用于一些非常简单的功能,这些功能不会改变并且经常使用,即使以这种代价也需要轻微的性能问题。

编辑以回应 Josh O'Brien 的评论:
我不确定这说明了他的想法,但是
library(compiler)
ff <- compile(function(...){.Internal(paste0(.Primitive("list")("this","and","that"),NULL))})
ff2 <- compile(function(...){.Internal(paste0(list("this","and","that"),NULL))})
microbenchmark(eval(ff),eval(ff2),times=10000)
> microbenchmark(eval(ff2),eval(ff),times=10000)
Unit: microseconds
expr min lq mean median uq max neval
eval(ff2) 1.621 2.026 2.356761 2.026 2.431 144.257 10000
eval(ff) 1.621 2.026 2.455913 2.026 2.431 89.148 10000
并查看从 microbenchmark 生成的图(只需用 plot() 将其包装以自己查看)运行了很多次,看起来那些在统计上具有相同的性能,尽管看起来像 ff2 的“max”值更差-案子。我不知道该怎么做,但也许这会对某人有所帮助。所以所有这些基本上都说它们编译成相同的代码。这是否意味着他的评论就是答案?

最佳答案

原因.Internal(paste0(.Primitive("list")("this","and","that"),NULL))较慢似乎是因为Josh O'Brien猜到了。调用.Primitive("list")直接产生一些额外的开销。

您可以通过一个简单的示例查看效果:

require(compiler)
pl <- cmpfun({.Primitive("list")})
microbenchmark(list(), .Primitive("list")(), pl())
# Unit: nanoseconds
# expr min lq median uq max neval
# list() 63 98.0 112.0 140.5 529 100
# .Primitive("list")() 4243 4391.5 4486.5 4606.0 16077 100
# pl() 79 135.5 148.0 175.5 39108 100

也就是说,您将无法提高 .Primitive 的速度和 .Internal从 R 提示符。它们都是 C 代码的入口点。

并且没有理由尝试替换对 .Primitive 的调用与 .Internal .这是递归的,因为 .Internal本身就是一个原语。
> .Internal
function (call) .Primitive(".Internal")

如果您尝试调用 .Internal,您会遇到同样的缓慢情况。 “直接”......如果您编译“直接”调用,则类似的“加速”。
Internal. <- function() .Internal(paste0(list("this","and","that"),NULL))
Primitive. <- function() .Primitive(".Internal")(paste0("this","and","that"),NULL)
cPrimitive. <- cmpfun({Primitive.})
microbenchmark(Internal., Primitive., cPrimitive., times=1e4)
# Unit: nanoseconds
# expr min lq median uq max neval
# Internal. 26 27 27 28 1057 10000
# Primitive. 28 32 32 33 2526 10000
# cPrimitive. 26 27 27 27 1706 10000

关于r - .Primitive 和 .Internal 的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30194281/

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