[spip-dev] proposition : abandon du foreach()

D’après http://www.phpbench.com/ cette fonction est très gourmande en temps.
L’auteur recommande de remplacer :

  • foreach($aHash as $val); // Total time: 17 µsview code

par
while(list(,$val) = each($aHash)); // Total time: 4 µsview code

  • foreach($aHash as $key => $val); //Total time: 19 µsview code

par
while(list($key,$val) = each($aHash)); //Total time: 4 µsview code

  • foreach($aHash as $key=>$val) $tmp[] = $aHash[$key]; // Total time: 41 µsview code
    par
    while(list($key) = each($aHash)) $tmp[] = $aHash[$key]; // Total time: 3 µsview code

Il y a 635 appels à foreach() dans ecrire/
Il y a peut-être une petite optimisation à faire là dessus, avec une bonne expression régulière…

.Gilles

2008/6/3 Gilles Vincent <gilles.vincent@gmail.com>:

D’après http://www.phpbench.com/ cette fonction est très gourmande en temps.
L’auteur recommande de remplacer :

Oubliez ce que j’ai proposé :

  1. D’une part,
    l’utilisation de tableaux multidimensionnels empêche une substitution générique.

Voici quand même, si ça sert à qqn, le script le plus proche auquel j’étais parvenu :

#!/bin/bash

for file in find . -type f \! -regex '.*\.svn.*'
do
sed ‹ /foreach($/s/foreach[ ]((([^ ]) as ([^ ])=>[ ]([^)])))/while(list(\3,\4) = each(\2))/g’ $file >> $file.old
mv $file.old $file
#ne fonctionne pas systematiquement – probleme de typage ?
sed '/foreach[ ]
($/s/foreach((([^ ]) as ([^ ])[ ]))/while(list(,\3) = each(\2))/g › $file >> $file.old
mv $file.old $file
done

On peut dire que ça foutait un joyeux bordel :slight_smile:

  1. D’autre part,
    j’aurais dû regarder à 2 fois avant de me lancer dans les tests : les benchs disent un peu tout et n’importe quoi
    Il semble que le while() fonctionne mieux sous PHP5 (à valider)

http://www.php.lt/benchmark/phpbench.php (pas de source)
http://m-fernandez.developpez.com/articles/php/bench/
http://iubito.developpez.com/php/bench.php?test=foreach

.Gilles

Gilles Vincent a écrit :

2008/6/3 Gilles Vincent <gilles.vincent@gmail.com <mailto:gilles.vincent@gmail.com>>:

    D'après http://www.phpbench.com/ cette fonction est très gourmande
    en temps.
    L'auteur recommande de remplacer :

Oubliez ce que j'ai proposé :

Je ne m'étais pas trop posé la question. J'avais entendu que foreach était plus long effectivement. J'ai donc aussi testé quelques bench proposés (php 4.4.3 de Free -http://marcimat.free.fr/bench.php), php 5.1.2 (http://magraine.net/bench.php)(Ubuntu 6.06 Dapper Drake), php 5.2.4 (local)(Ubuntu 8.04 Gusty Gibbon)

Les tests sont assez cohérents entre php4 et php5 pour les benchs proposés par le site phpbench que j'ai utilisé (source collée ici : Friendpaste - Bench php (quelques exemples issus de http://www.phpbench.com/)), mais montrent (pour mes cas) *justement l'inverse*, à savoir que Foreach est plus rapide que le While-list-each !!!!

C'est étonnant, car j'ai utilisé le même code qu'eux !

2008/6/3 Matthieu Marcillaud <marcimat@free.fr>:

Gilles Vincent a écrit :

2008/6/3 Gilles Vincent <gilles.vincent@gmail.com mailto:[gilles.vincent@gmail.com](mailto:gilles.vincent@gmail.com)>:

D’après http://www.phpbench.com/ cette fonction est très gourmande
en temps.
L’auteur recommande de remplacer :

Oubliez ce que j’ai proposé :

Je ne m’étais pas trop posé la question. J’avais entendu que foreach était plus long effectivement. J’ai donc aussi testé quelques bench proposés (php 4.4.3 de Free -http://marcimat.free.fr/bench.php), php 5.1.2 (http://magraine.net/bench.php)(Ubuntu 6.06 Dapper Drake), php 5.2.4 (local)(Ubuntu 8.04 Gusty Gibbon)

Les tests sont assez cohérents entre php4 et php5 pour les benchs proposés par le site phpbench que j’ai utilisé (source collée ici : http://www.friendpaste.com/y2rnSyWV), mais montrent (pour mes cas) justement l’inverse, à savoir que Foreach est plus rapide que le While-list-each !!!

C’est étonnant, car j’ai utilisé le même code qu’eux !

En fait moi c’est pareil :

voici ce que ça donne
→ sur Dedibox (sous Fedora / PHP5) :
http://tech-nova.fr/test/phpbench.php

→ sur OVH 270Plan :
http://www.grimedif.com/phpbench.php (PHP4)

→ sur infomaniak.ch : (PHP5)
http://pressesuisse.ch/phpbench.php

→ sur Free :
http://hce.free.fr/phpbench.php (PHP4)

Pour les PHP4, le test sur les for…loop ne fonctionne pas (il faut désactiver le test 3).
En tout cas il y a de grosses différences selon les hébergeurs (entre Free et infomaniak il y a une rapport de 10 :wink:

Sous PHP4 je note que
array_keys($aHash); array_values($aHash);
est plus rapide que tout.
Ce n’est pas le cas sous PHP5 (loin de là).

Sinon les tests sont peut-être aussi discutables car pour les foreach() par ex. il n’y a pas d’affectation de variable / traitement comme « dans la vrai vie ».
Je n’ai pas trop d’idée là dessus.

Et vous, quel est le bench de votre hébergeur ?
Je suis curieux de voir ce que ça donne chez 1&1, Gandi, Amen, etc…

.Gilles

Voilà le benchmark sur un site de 1et1.fr :
http://s240814051.onlinehome.fr/phpbench.php

C’est pas des plus véloce (ma Dédibox fait mieux :slight_smile:

@+

.Gilles

Bonjour à tous,

Gilles Vincent a écrit :

[...]

voici ce que ça donne
[...]

-> sur OVH 270Plan :
http://www.grimedif.com/phpbench.php (PHP4)

Bonjour

Est ce que tu pourrais faire le même test en php5 sur OVH?

Il faut ajouter dans un .htaccess :

SetEnv PHP_VER 5

et éventuellement :

SetEnv REGISTER_GLOBALS 0
SetEnv ZEND_OPTIMIZER 1
SetEnv MAGIC_QUOTES 1

Je ne sais plus à quoi sert les magic_quotes... mais j'ai un site
Spip qui tourne avec tout ça sur OVH.

Ainsi, on aurait une bonne comparaison entre php4 et php5 sur un
même hébergeur.

Peut être qu'il faut désactiver zend_optimizer...

A bientôt
Grégoire