为什么diag功能这么慢?[在R 3.2.0或更早版本中]

坦率

我正在查看此答案中的基准,并希望将其与diag(用于其他答案中)进行比较。不幸的是,似乎diag需要花费很多时间:

nc  <- 1e4
set.seed(1)
m <- matrix(sample(letters,nc^2,replace=TRUE), ncol = nc)

microbenchmark(
  diag = diag(m),
  cond = m[row(m)==col(m)],
  vec  = m[(1:nc-1L)*nc+1:nc],
  mat  = m[cbind(1:nc,1:nc)],
times=10)

评论:我用进行了测试identical我从这个作业问题的答案之一中得出“ cond” 结果类似于整数矩阵,1:26而不是letters

结果

Unit: microseconds
 expr         min          lq         mean       median          uq         max neval
 diag  604343.469  629819.260  710371.3320  706842.3890  793144.019  837115.504    10
 cond 3862039.512 3985784.025 4175724.0390 4186317.5260 4312493.742 4617117.706    10
  vec     317.088     329.017     432.9099     350.1005     629.460     651.376    10
  mat     272.147     292.953     441.7045     345.9400     637.506     706.860    10

这只是一个矩阵子集运算,所以我不知道为什么会有这么多的开销。展望功能里面,我看到了几个检查,然后c(m)[v],在v处于“VEC”基准测试中使用相同的载体。定时这两个...

v <- (1:nc-1L)*nc+1:nc
microbenchmark(diaglike=c(m)[v],vec=m[v])
# Unit: microseconds
#      expr        min          lq        mean     median          uq        max neval
#  diaglike 579224.436 664853.7450 720372.8105 712649.706 767281.5070 931976.707   100
#       vec    334.843    339.8365    568.7808    646.799    663.5825   1445.067   100

...似乎我找到了罪魁祸首。所以,对我的问题的新变化是:为什么会出现一个看似不必要的,非常耗时cdiag

史蒂夫·科林

概要

3.2.1版开始(世界著名的宇航员)diag()已收到更新。讨论转移到r-devel,在那里注意到它去除了c()非名称属性,并且可能是为什么将其放置在那里。尽管有些人担心删除c()会在类似矩阵的对象上引起未知的问题,但Peter Dalgaard发现:“c()内部diag()起作用的唯一情况M[i,j] != M[(i-1)*m+j]ANDc(M)将按M列的主要顺序进行字符串化,这样M[i,j] == c(M)[(i-1)*m+j]。”

Luke Tierney测试了@Frank的删除c(),发现它对CRAN或BIOC没有任何影响,因此在第27行实现了用x [...]替换c(x)[...] 这导致相对较大的加速diag()以下是一项速度测试,显示了R 3.2.1版本的改进diag()

library(microbenchmark)
nc  <- 1e4
set.seed(1)
m <- matrix(sample(letters,nc^2,replace=TRUE), ncol = nc)

    microbenchmark(diagOld(m),diag(m))
    Unit: microseconds
           expr        min          lq        mean      median         uq        max neval
     diagOld(m) 451189.242 526622.2775 545116.5668 531905.5635 540008.704 682223.733   100
        diag(m)    222.563    646.8675    644.7444    714.4575    740.701   1015.459   100

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章