¿Por qué la función diag es tan lenta? [en R 3.2.0 o anterior]

Estaba mirando los puntos de referencia enesta respuesta, y quería compararlos condiag (usado en una respuesta diferente). Lamentablemente, parece quediag toma edades:

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)

Comentarios: Probé estos conidentical. Tomé "cond" de una de las respuestas aesta pregunta de tarea. Los resultados son similares con una matriz de enteros,1:26 en lugar deletters.

Resultados:

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

Es solo una operación de subconjunto de matrices, por lo que no sé por qué hay tanta sobrecarga. Mirando dentro de la función, veo algunas comprobaciones y luegoc(m)[v], dóndev es el mismo vector utilizado en el punto de referencia "vec". Sincronizando estos dos ...

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

... parece que he encontrado a mi culpable. Entonces, la nueva variación en mi pregunta es:¿Por qué hay un servicio aparentemente innecesario y que consume tanto tiempo?c endiag?

Respuestas a la pregunta(1)

Su respuesta a la pregunta