2010-02-09 3 views
0

Je suis micro-optimisant cette fonction et ai un peu de problème où à l'intérieur d'une boucle je vérifie si une valeur en dehors de la boucle est 0, si ainsi appeler la fonction et de même dans la fonction qu'elle appelle . Comment pourrais-je le refactoriser afin qu'il n'y ait pas de logique conditionnelle (qui est lente) à l'intérieur de ces boucles.PHP Optimiser la fonction dans la boucle

foreach($this->layer[$l]->objs as $obj) 
{ 
    //Horrific code to save 20ms :(
    ($l===0) ? $obj->myfunc_clean($var,$var2) : $obj->myfunc($var,$var2); 
} 

J'ai besoin de se débarrasser de la condition $l===0 parce que cette condition dans une boucle de milliers d'objets le ralentit considérablement. De plus, j'ai une fonction qui doit être traitée normalement mais l'autre doit désactiver les variables temporaires quand elle se termine (en supposant que l soit 0). La fonction myfunc a également une boucle sur encore plus d'objets, d'où la nécessité d'appeler des fonctions séparées pour économiser encore plus de logique conditionnelle. Cela peut ressembler à une optimisation prématurée mais croyez-moi, pour mon application, économiser 1 milliseconde peut sauver de précieuses secondes (probablement environ 10 000 itérations sinon plus). Donc, s'il vous plaît pas de réponses sur l'optimisation prématurée est la racine de tous les maux et autres joyeusetés. Ce n'est certainement pas prématuré. Vous ne pouvez pas simplement mettre le test en dehors de la boucle?

+0

Bien que je trouve inutile d'optimiser cela, http://www.phpbench.com pourrait vous donner quelques autres idées. – Gordon

Répondre

3

if ($l === 0) 
    foreach($this->layer[$l]->objs as $obj) 
     $obj->myfunc_clean($var,$var2); 
else 
    foreach($this->layer[$l]->objs as $obj) 
     $obj->myfunc($var,$var2); 
1

juste faire deux boucles

if($l == 0) 
    foreach(...) myfunc_clean 
else 
    foreach(...) myfunc 
1

donc mon offre rapide est

if($l===0) 
{ 
    foreach($this->layer[$l]->objs as $obj) 
    { $obj->myfunc_clean($var,$var2) } 
} 
else 
{ 
    foreach($this->layer[$l]->objs as $obj) 
    { $obj->myfunc($var,$var2) } 
} 
1

Je suppose que les changements d'état pendant la boucle, sinon les deux boucles d'autres réponses fournissent donnent la répondre.

La condition est probablement lente car vous effectuez une comparaison de type sûr (===). Vous pourriez vouloir introduire une variable supplémentaire qui est toujours une valeur booléenne et définie en même temps pour que vous puissiez utiliser la comparaison générale.

Mais je doute que 10,000x fois une comparaison est votre problème. Vous devriez probablement vous concentrer sur les boucles à l'intérieur des autres fonctions qui seront exécutées plusieurs fois.

+0

J'ai juste essayé de faire un million de ces comparaisons de type: .2 secondes. Utilisez un profileur (xdebug par exemple), et regardez où le goulot d'étranglement * real * est ... – Wim

+0

@Wim, xdebug ne donnera pas les résultats de performance ligne par ligne, juste fonction par fonction. Ce sera inutile ici. – vava

+0

@vava Pas tout à fait inutile: vous pouvez diviser une fonction en plusieurs fonctions (une pour chaque ligne, finalement, mais en général vous n'avez pas besoin d'aller aussi loin pour trouver le contrevenant). Un peu encombrant, je le sais, mais généralement une approche méritante. – Wim