Quelle est la différence de performances (le cas échéant) entre ces trois approches, toutes deux utilisées pour transformer un tableau en un autre tableau?
- En utilisant
foreach
- Utilisation
array_map
avec la fonction lambda / fermeture - Utilisation
array_map
avec une fonction / méthode 'statique' - Existe-t-il une autre approche?
Pour être clair, regardons les exemples, tous faisant de même - en multipliant le tableau de nombres par 10:
$numbers = range(0, 1000);
Pour chaque
$result = array();
foreach ($numbers as $number) {
$result[] = $number * 10;
}
return $result;
Carte avec lambda
return array_map(function($number) {
return $number * 10;
}, $numbers);
Mapper avec la fonction 'statique', passée comme référence de chaîne
function tenTimes($number) {
return $number * 10;
}
return array_map('tenTimes', $numbers);
Existe-t-il une autre approche? Je serai heureux d'entendre en fait toutes les différences entre les cas ci-dessus, et toutes les entrées pour lesquelles l'un devrait être utilisé au lieu d'autres.
Réponses:
FWIW, je viens de faire le benchmark puisque l'affiche ne l'a pas fait. Fonctionnant sous PHP 5.3.10 + XDebug.
UPDATE 2015-01-22 comparer avec la réponse de mcfedr ci-dessous pour des résultats supplémentaires sans XDebug et une version PHP plus récente.
J'obtiens des résultats assez cohérents avec des nombres de 1M sur une douzaine de tentatives:
En supposant que la vitesse terne de la carte à la fermeture était causée par la fermeture éventuellement évaluée à chaque fois, j'ai également testé comme ceci:
Mais les résultats sont identiques, confirmant que la fermeture n'est évaluée qu'une seule fois.
MISE À JOUR 02/02/2014: vidage des opcodes
Voici les vidages de l'opcode pour les trois rappels. Premièrement
useForeach()
:Puis le
useMapClosure()
et la fermeture qu'il appelle:
puis la
useMapNamed()
fonction:et la fonction nommée appelle,
_tenTimes()
:la source
useMapNamed
c'est en fait plus rapide queuseArray
. J'ai pensé que cela valait la peine d'être mentionné.lap
, ne voulez-vous pas l'range()
appel au-dessus du premier appel microtime? (Bien que probablement insignifiant par rapport au temps de la boucle.)Il est intéressant d'exécuter ce benchmark avec xdebug désactivé, car xdebug ajoute beaucoup de surcharge, en particulier pour les appels de fonction.
Ceci est le script de FGM exécuté en utilisant 5.6 avec xdebug
Sans xdebug
Ici, il n'y a qu'une très petite différence entre la version foreach et la version de fermeture.
Il est également intéressant d'ajouter une version avec une fermeture avec un
use
Pour comparaison, j'ajoute:
Ici, nous pouvons voir que cela a un impact sur la version de fermeture, alors que le tableau n'a pas sensiblement changé.
19/11/2015 J'ai également ajouté des résultats en utilisant PHP 7 et HHVM à des fins de comparaison. Les conclusions sont similaires, même si tout est beaucoup plus rapide.
la source
array_map
(et ses fonctions associéesarray_reduce
,array_filter
) vous permettent d'écrire un beau code. Siarray_map
c'était beaucoup plus lent, ce serait une raison d'utiliserforeach
, mais c'est très similaire, donc je vais l'utiliserarray_map
partout où cela a du sens.C'est intéressant. Mais j'ai un résultat opposé avec les codes suivants qui sont simplifiés par rapport à mes projets actuels:
Voici mes données et codes de test:
Le résultat est:
Mes tests étaient dans l'environnement de production LAMP sans xdebug. Je suis en train d'errer xdebug ralentirait les performances de array_map.
la source
array_map
;)array_map
et l'foreach
utilisation de Xhprof. Et son intéressantarray_map
consomme plus de mémoire que «foreach».