Qual é a diferença de desempenho (se houver) entre essas três abordagens, ambas usadas para transformar uma matriz em outra matriz?
- Usando
foreach
- Usando
array_map
com a função lambda / encerramento - Usando
array_map
com função / método 'estático' - Existe alguma outra abordagem?
Para me esclarecer, vejamos os exemplos, todos fazendo o mesmo - multiplicando a matriz de números por 10:
$numbers = range(0, 1000);
Para cada
$result = array();
foreach ($numbers as $number) {
$result[] = $number * 10;
}
return $result;
Mapa com lambda
return array_map(function($number) {
return $number * 10;
}, $numbers);
Mapa com a função 'estática', passada como referência de string
function tenTimes($number) {
return $number * 10;
}
return array_map('tenTimes', $numbers);
Existe alguma outra abordagem? Ficarei feliz em ouvir, na verdade, todas as diferenças entre os casos acima e quaisquer sugestões de por que um deve ser usado em vez de outros.
Respostas:
FWIW, eu apenas fiz o benchmark, pois o cartaz não o fez. Rodando no PHP 5.3.10 + XDebug.
ATUALIZAÇÃO 2015-01-22 Compare com a resposta do mcfedr abaixo para obter resultados adicionais sem o XDebug e uma versão mais recente do PHP.
Eu obtenho resultados bastante consistentes com números de 1 milhão em uma dúzia de tentativas:
Supondo que a velocidade sem brilho do mapa no fechamento foi causada pelo fato de o fechamento ser avaliado a cada vez, também testei assim:
Mas os resultados são idênticos, confirmando que o fechamento é avaliado apenas uma vez.
02-02-2014 ATUALIZAÇÃO: despejo de opcodes
Aqui estão os dumps do opcode para os três retornos de chamada. Primeiro
useForeach()
:Então o
useMapClosure()
e o fechamento que chama:
então a
useMapNamed()
função:e a função nomeada que chama
_tenTimes()
:fonte
useMapNamed
é realmente mais rápido queuseArray
. Pensei que valia a pena mencionar.lap
, você não deseja arange()
chamada acima da primeira chamada de microtime? (Embora provavelmente insignificante em comparação com o tempo para o loop).É interessante executar esse benchmark com o xdebug desativado, pois o xdebug adiciona bastante sobrecarga, especialmente às chamadas de função.
Este é o script do FGM executado usando o 5.6 With xdebug
Sem xdebug
Aqui há apenas uma diferença muito pequena entre a versão foreach e encerramento.
Também é interessante adicionar uma versão com um fechamento com um
use
Para comparação, eu adiciono:
Aqui podemos ver que isso afeta a versão de fechamento, enquanto a matriz não mudou visivelmente.
19/11/2015 Agora também adicionei resultados usando o PHP 7 e o HHVM para comparação. As conclusões são semelhantes, embora tudo seja muito mais rápido.
fonte
array_map
(e suas funções relacionadasarray_reduce
,array_filter
) permitem escrever código bonito. Searray_map
fosse muito mais lento, seria uma razão para usarforeach
, mas é muito semelhante, então eu usarei emarray_map
qualquer lugar que faça sentido.É interessante. Mas eu tenho um resultado oposto com os seguintes códigos que são simplificados em meus projetos atuais:
Aqui estão meus dados e códigos de teste:
O resultado é:
Meus testes foram no ambiente de produção LAMP sem xdebug. Estou vagando pelo xdebug diminuiria o desempenho do array_map.
fonte
array_map
;)array_map
eforeach
uso do Xhprof. E é interessantearray_map
consome mais memória que `foreach '.