Por que a função diag é tão lenta? [no R 3.2.0 ou anterior]
Eu estava olhando para os benchmarks emesta respostae queria compará-los comdiag
(usado em uma resposta diferente). Infelizmente, parece quediag
leva idades:
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)
Comentários: Eu testei estes comidentical
. Peguei "cond" de uma das respostas paraesta pergunta de lição de casa. Os resultados são semelhantes com uma matriz de números inteiros,1:26
ao invés 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
É apenas uma operação de subconjunto de matrizes, então não sei por que há tanta sobrecarga. Olhando dentro da função, vejo algumas verificações e depoisc(m)[v]
, Ondev
é o mesmo vetor usado no benchmark "vec". Cronometrando esses dois ...
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 encontrei meu culpado. Então, a nova variação na minha pergunta é:Por que existe uma aparentemente desnecessária e muito demoradac
nodiag
?