【问题标题】:Is there a difference between a^2 and a^2L?a^2 和 a^2L 有区别吗?
【发布时间】:2016-02-11 18:07:55
【问题描述】:

R中的a^2a^2L有区别吗?

速度差?

精度?

到目前为止,我没有看到,只是想知道 ^2 是否实现为 log/exp 对,但 ^2L 实现为乘法。如果a 不仅仅是一个向量呢?

更新

不,它不是重复的,我知道 22L 之间的区别。问题是,这种差异对电力运营商有影响吗?

【问题讨论】:

  • 如果有差异,你可以自己做基准测试......
  • 也许吧。 mlutils.cR_powR_pow_di ,但我还没有检查更上游的 R_pow_di 是否被解析器使用。
  • FWIW 关于速度,使用 2 比使用 2L非常轻微,但差异是恕我直言可以忽略不计(在我的机器上平均差异 10 毫秒,在长度为 1e7) 的向量
  • 我用microbenchmark 对它进行了多次基准测试,它们一直在翻转哪个更慢,所以我认为它们是相当的。使用print((1/3)^2, digits = 22),它们似乎也有相同的浮点错误。根据?`^`^是用C的pow实现双打;它没有说整数。
  • @MichaelChirico 我认为这里的结论是“速度没有差异”......

标签: r


【解决方案1】:

我的结论是它稍微当且仅当基数也是整数,在标量上 .

我的基准:

library(microbenchmark)
set.seed(1230)
num <- rnorm(1L)
int <- sample(100L, 1L)
microbenchmark(times = 100000L,
               num^2L,
               num^2,
               int^2L,
               int^2)

我的机器上的时间安排:

# Unit: nanoseconds
#    expr min  lq     mean median  uq      max neval
#  num^2L  99 115 161.8495    121 166    11047 1e+05
#   num^2  97 113 196.8615    119 165  3645369 1e+05
#  int^2L  89 107 140.3745    111 120     3319 1e+05
#   int^2  98 115 525.1727    120 166 34776551 1e+05

如果 base 或 exponent 是数字,则中位时间基本相同(尽管 num ^ num 可能有一个肥大的上尾?)。

大小的惩罚

尽管integer ^ integer 在标量上具有优势,但似乎(正如@A.Webb 在他自己的回答中所解释的那样)对于任何合理大小的向量,numeric ^ numeric 更快,并且对于合理的向量中等大小的常见范围,它的速度要快得多。

500 次基准测试的结果:

set.seed(1230)
ns <- as.integer(10^(seq(0, 6, length.out = 500L)))
mbs <- sapply(ns, function(n){
  num = rnorm(n); int = as.integer(num)
  summary(microbenchmark(times = 2000L, num ^ 2L, num ^ 2, int ^ 2L, int ^ 2), 
          unit = "relative")$median
})

这第一个情节得到了事情的要旨。 n 表示numerici 表示integer

最终,向量大小的固定成本确实会蚕食优势:

只有在可忽略不计的长度上,i ^ i 最快:


绘制的要点是这样的:

matplot(ns[ns < 5000], t(mbs[ , ns < 5000]),
        type = "l", lty = 1L, lwd = 3L,
        xlab = "length", ylab = "Relative Time",
        main = "Through Length 5000",
        col = c("black", "red", "green", "blue"))
legend("topleft", c("n ^ i", "n ^ n", "i ^ i", "i ^ n"),
       col = c("black", "red", "green", "blue"),
       lty = 1L, lwd = 3L)

【讨论】:

    【解决方案2】:

    R 在内部使用整数指数版本R_pow_di,但^ operator 仅调用R_pow。话虽如此,R_pow 确实 特殊情况 x^2x*x。因此,精度是相同的,但 2L 版本由于 C 级别的 long->double 强制转换应该稍微慢一些。这在以下基准中得到了证明。

    lngs<-rep(2L,1e6)
    dbls<-rep(2.0,1e6)
    n<-sample(100,1e6,replace=TRUE)
    x<-rnorm(1e6)
    microbenchmark(x^lngs,x^dbls,n^lngs,n^dbls)
    # Unit: milliseconds
    #    expr       min        lq      mean    median       uq      max neval cld
    #  x^lngs  8.489547  9.804030 12.543227 11.719721 13.98702 19.92170   100  b 
    #  x^dbls  5.622067  6.724312  9.432223  7.949713 10.89252 59.15342   100 a  
    #  n^lngs 10.590587 13.857297 14.920559 14.200080 16.65519 19.55346   100   c
    #  n^dbls  8.331087  9.699143 12.414267 11.403211 14.20562 19.66389   100  b 
    

    这没什么好失眠的。

    链接转到源镜像。请注意,R_ADDR_SUBR_MULR_DIV 被定义为 C 宏以利用类型重载,但 R_POW 被定义为内联 x^2 = x*x 特殊情况然后调用 R_pow(下案子)。在 R_pow 中再次检查该特殊情况将是重复的,除非 R_pow 在内部其他地方被调用。

    【讨论】:

      猜你喜欢
      • 2021-09-17
      • 1970-01-01
      • 2012-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-27
      相关资源
      最近更新 更多