【问题标题】:Speed comparison of sapply with a composite functionsapply 与复合函数的速度比较
【发布时间】:2011-06-03 18:27:27
【问题描述】:
> system.time(sapply(rnorm(1000000,0,1), function (x) round(x,2)))
   user  system elapsed 
   2.78    0.11    2.89 
> system.time(round(rnorm(1000000,0,1),2))
   user  system elapsed 
   0.29    0.00    0.30 

在阅读 R 提示问题的答案后,我正在尝试这个。在上述情况下,我没想到 sapply 比等效的复合函数慢一个数量级。有谁知道为什么会这样?如果我理解正确,sapply 将矢量化并接近最佳速度。

【问题讨论】:

  • 科斯克是对的。 sapply 只是为真正的矢量化创造了一种错觉或糟糕的替代品。如果可以,您应该尝试使用固有的矢量化函数构建所有转换。
  • sapply 的主要目的是使循环更易于阅读(并节省输入),而不是加快速度。

标签: r performance runtime


【解决方案1】:

可能 sapply 是一个简单的 lapply 包装器,它没有被矢量化。试试这个代码:

system.time(sapply(rnorm(10), function (x) {print(length(x)); round(x,2)}))

并在此处查看实现:https://svn.r-project.org/R/trunk/src/main/apply.c

【讨论】:

    【解决方案2】:

    这里没有什么可 sapply 的 - 你只给它一个向量 - 而不是向量列表,并且 sapply 将结果转换为(单列)矩阵。

    sapply 正在为您简化结果,但这样做必须生成一个数组。

    如果你给它一个列表比较:

    system.time(sapply(list(rnorm(1000000,0,1)), function (x) round(x,2))) 
    user  system elapsed 
     0.22    0.00    0.22 
    
    system.time(sapply(rnorm(1000000,0,1), function (x) round(x,2))) 
    user  system elapsed 
    4.21    0.00    4.21 
    

    【讨论】:

    • sapply 调用 lapply,它对向量进行元素操作。
    • 感谢 Hadley,我不确定这里到底发生了什么 - 显然是这里的 s(apply) 简化需要额外的时间?
    • 您好,第一个(列表)案例类似于:for(i=1)round(x[[i]]),其中 x 是列表(rnorm(100000))。它与调用 round(rnorm(100000)) 非常相似。第二种情况类似于:for(i=1:100000)round(x[i]),其中 x 是 rnorm(100000)。额外的时间不是因为简化,而是循环。
    • 感谢所有评论者和回答,因为我显然不明白 sapply 并且将不得不更深入地研究矢量化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    • 1970-01-01
    • 2014-09-21
    • 2023-03-03
    相关资源
    最近更新 更多