
Que bonita demostração Benilton, vou fazer a liçãod e casa aqui, valeu! att, FH 2011/6/14 Benilton Carvalho <beniltoncarvalho@gmail.com>
Atualmente, a ideia de *apply() ser mais rapido que for() nao eh exatamente verdadeira.
A diferenca essencial (as far as users care) entre ambas eh que a familia *apply cria um objeto de resposta para cada elemento de entrada, ao passo que usuarios do for() fazem alocacao da resposta a objetos pre-existentes (o que dispara uma copia e, consequentemente, faz com que a execucao seja mais lenta).
Veja o exemplo abaixo (mude as dimensoes caso vc nao tenha RAM suficiente):
nc <- 1e6 nr <- 200
## com sapply set.seed(1) t0 <- system.time(res0 <- sapply(1:nr, function(x) rnorm(nc)))
## com for() usando o q a maioria de usuarios faz... set.seed(1) t1 <- system.time({res1 <- NULL; for (i in 1:nr) res1 <- cbind(res1, rnorm(nc))}) all.equal(res0, res1) ## deve ser TRUE rm(res0)
## com for() mais eficiente set.seed(1) t2 <- system.time({res2 <- matrix(NA, nc=nr, nr=nc); for (i in 1:nr) res2[,i] <- rnorm(nc)}) all.equal(res1, res2) ## deve ser TRUE rm(res1); gc()
## com lapply() set.seed(1) t3 <- system.time(res3 <- do.call(cbind, lapply(1:nr, function(x) rnorm(nc)))) all.equal(res2, res3) ## deve ser TRUE rm(res2, res3); gc()
## visualizando tempos message(sprintf('sapply...........: %2.4f', t0[3])) message(sprintf('for() usual......: %2.4f', t1[3])) message(sprintf('for() pre-aloc..: %2.4f', t2[3])) message(sprintf('do.call+lapply: %2.4f', t3[3]))
Os resultados que obtive na minha maquina sao:
sapply...........: 20.5400 for() usual......: 207.3900 for() pre-aloc..: 21.7730 do.call+lapply: 18.3960
Take-home messages:
1) for() mais lento e' fato qdo a programacao e' ineficiente; 2) lapply() e' sempre mais eficiente que sapply()
Take-home exercise: repita o for() com pre-alocacao usando listas, combinando o resultado com do.call()... Isso e' tao rapido quanto o do.call+lapply (na verdade, na minha execucao, ele eh ainda ligeiramente mais rapido... levando 18.385s)...
b
2011/6/14 Junior Beleti <beleti.junior@gmail.com>:
Boa noite,
gostaria de entender o funcionamento da função apply, mais precisamente lapply, para loops.
Já conheço a descrição de seu funcionamento:
‘lapply’ returns a list of the same length as ‘X’, each element of which is the result of applying ‘FUN’ to the corresponding element of ‘X’.
Mas o que eu gostaria de saber é como ele funciona em sua essência. Por exemplo, utilizar um lapply ao invés de um loop "for" é mais rápido. Eu gostaria de saber o porque, ou seja, como o lapply é implementado.
Não sei se fui claro, mas gostaria de encontrar a implementação da função lapply, o que não encontrei no diretório do pacote "base".
Se alguém puder ajudar.
Também peço desculpas por não ter dado grandes contribuições para a lista, mas creio ter mais experiência em programação (lógica) de fato, do que no ambiente R.
Obrigado.
-- Carlos Roberto Beleti Junior Mestrado em Ciência da Computação Departamento de Informática Universidade Estadual de Maringá
_______________________________________________ R-br mailing list R-br@listas.c3sl.ufpr.br https://listas.inf.ufpr.br/cgi-bin/mailman/listinfo/r-br Leia o guia de postagem (http://www.leg.ufpr.br/r-br-guia) e forneça código mínimo reproduzível.
-- Successful people ask better questions, and as a result, they get better answers. (Tony Robbins) _______________________________________________ R-br mailing list R-br@listas.c3sl.ufpr.br https://listas.inf.ufpr.br/cgi-bin/mailman/listinfo/r-br Leia o guia de postagem (http://www.leg.ufpr.br/r-br-guia) e forneça código mínimo reproduzível.