11/07/2011

PHP : for() mieux que foreach(), un mythe ?

Dans mon boulot je dois fournir pas mal de PHP, qui sera parfois mis à mal et donc doit être un peu performant. Un jour au détour d'un backlog IRC je vois passer un argument du type "il faut remplacer les foreach() par des for() sinon ça consomme trop de mémoire".

Ah bon ?

Deux coups de googlage et voilà d'autres commentaires du même ordre, mais aucun n'est soutenu par des mesures, du coup faut que j'essaie.

Pour tester, j'ai le petit script suivant :


<?php
$largearray = array();
for ($i = 0, $max = 1000; $i < $max; $i++) {
for ($j = 0, $max = 100; $j < $max; $j++) {
$largearray[$i][$j] = rand(0, 100000);
}
}

$base = memory_get_usage();
foreach ($largearray as $value) {
$foo = $value; // oui, ca ne sert a rien
}
print "foreach : ".(memory_get_peak_usage() - $base)."\n";

$base = memory_get_usage();
for ($i = 0, $max = count($largearray); $i < $max; $i++) {
$foo = $largearray[$i];
}
print "for : ".(memory_get_peak_usage() - $base)."\n";
?>


C'est d'une simplicité criminelle : d'abord on se remplit un array bidimensionnel avec des valeurs aléatoires, ensuite on va boucler dessus et bêtement copier chaque sous-tableau dans une variable qui ne sert à rien. Avant de boucler on obtient l'usage mémoire, pour mieux distinguer ce que génère le parcours.

Seulement voilà, moi on me parlait de "deux fois moins de mémoire" et j'obtiens ceci à l'exécution (valeurs en octets) :

foreach : 1540
for : 1496

Quelqu'un a pu observer un grand écart de consommation mémoire entre un for() et un foreach() sur les mêmes données ?

4 commentaires:

  1. Il faudrait que je teste sur une de mes bases de données à 8M enregistrement au boulot. Je ferai ça si j'ai un moment et si j'y pense.

    RépondreSupprimer
  2. Je serais curieux aussi de comparer le temps d'éxécution (microtime). Et je me demande aussi si le fait que l'assignation de variable est différente ($var = $array[$key] au lieu de $var = $othervar) pourrait changer quelque chose...

    +1 pour Enkimy, tester sur un volume de données énorme pourrait aider à visualiser la différence de manière plus précise.

    RépondreSupprimer
  3. Autant que je me souviennes, foreach et for utilise la même routine du core PHP ... My 2 cents...

    RépondreSupprimer
  4. Pour précision, j'ai eu un retour positif de quelqu'un qui a observé une différence : http://wildness.espix.org/index.php?post/2011/05/09/PHP5%3A-Memory-leak-with-object-arrays

    RépondreSupprimer