Style de codage

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Style de codage

Re: Style de codage

par mere-teresa » 02 nov. 2011, 13:59

Re: Style de codage

par devlop78 » 20 sept. 2011, 18:46

Rhooo vu toutes les fautes sur l'ensemble du forum, je peux bien moi aussi en faire de temps en tant (<= hi hi hi)

Par contre j'adore être hors sujet, comme : Quelqu'un sait où on peut acheter l'éléphant peluche PHP ?

Re: Style de codage

par Nagol » 20 sept. 2011, 18:41

Sans vouloir me venter
ça veut dire coller un vent? :)

Re: Style de codage

par devlop78 » 20 sept. 2011, 18:40

Et pour revenir au pseudo tableau numérique (qui n'est qu'un tableau associé en fait) :
<?php
$a = array (5=>'cinq',7=>'sept',2=>'deux');
array_shift($a);
var_dump($a);
affichera
0 => string 'sept' (length=4)
1 => string 'deux' (length=4)
L'importance n'est pas la clé, mais la place de l'élément dans le tableau. C'est aussi pour ça que je ne donne aucune importance à la clé avec PHP, et que je n'utilise plus for(). A l'extreme while(list($cle,$valeur) = each()) est plus logique que for, on est vraiment sur une notion de pointeur.

Re: Style de codage

par devlop78 » 20 sept. 2011, 18:32

Sans vouloir me venter, les benchmarks que j'ai mis sont intéressants :

Un unset() sur un élément de fin de tableau est près de 8 fois plus rapide que un array_pop. Les pire sont les modifications en début ou milieu de tableau, d'après moi parce qu'ils doivent repositionner les index (donc parcourir toute une partie du tableau pour déplacer les clés).

Re: Style de codage

par devlop78 » 20 sept. 2011, 18:25

Oki (mon incompréhension était purement syntaxique). On est donc d'accord :)

Enfin, les piles ça se gère pas mal à coup de array_shift/unshift quand même
C'est pas top niveau perf, et là vraiment, surtout le FIFO. Mais je précise Array, puisqu'une pile peut être objet, et la SPL propose des piles.

Re: Style de codage

par Nagol » 20 sept. 2011, 18:21

pour boucler avec un for sur un tableau troué ou indéxé avec du texte y'a array_keys($arr) aussi, pour boucler sur un object y'a array_keys(get_object_vars($obj)), si je disais du mal de foreach c'est que j'avais passé du temps à optimiser du code y'a un bout de temps et l'optimisation principale consistait à virer les foreach, mais bon la mes tests c'est du php 5.3.8 peut-être qu'il y'avait un facteur bug, ou autre à l'époque qui n'est plus vrai maintenant.

Re: Style de codage

par popy » 20 sept. 2011, 18:17

Oki (mon incompréhension était purement syntaxique). On est donc d'accord :)

Enfin, les piles ça se gère pas mal à coup de array_shift/unshift quand même

Re: Style de codage

par devlop78 » 20 sept. 2011, 18:08

Ce que je veux dire ?

$array = array(0,1,2,3,4);
unset($array[2]);

for ($i=0;$i<count($array);$i++)
{
echo $array[$i];
}

Affichera :

01

NOTICE ERROR : Undefined index 2 in $array line x file y

3

$array[2] devenant implicitement null à l'appel (comme toute variable inexistante ou sans attribution de valeur). Et le "4" ne s'affichera pas (oui count n'est pas l'équivalent de Array.length en JavaScript ;))

Donc à moins d'utiliser des piles (qui sont logiquement sans trou) Array, ce sera soit Foreach soit While. Et je préfère foreach (d'autant qu'il est vraiment prévu pour l'itération, c'est sa tache dédiée !).

Re: Style de codage

par popy » 20 sept. 2011, 17:54

unset($tab[5]);
Un E_NOTICE + 1 null + le dernier oublié
Je suis pas sur de comprendre ce que tu veux dire, mais comme tu l'as dit précédement, foreach fonctionne très bien pour les listes à trou, contrairement aux for & while.

Donc, performances ridiculement meilleures dans certains cas + meilleure lisibilité + moins de code = j'utilise foreach :)

Re: Style de codage

par devlop78 » 20 sept. 2011, 17:42

Rien qu'un include est plus long que un foreach normal (pas sur 250 000 items quoi ...), faut-il pour autant s'empêcher d'avoir une classe par fichier, ou plutôt mettre en place des caches d'Op-codes et de vues finales (voire de pages complètes si tout est statique pour une période T).

Re: Style de codage

par macgawel » 20 sept. 2011, 17:31

Petit benchmark
(...)
Ce qui montre que le for est plus rapide que le foreach, en revanche le foreach est effectivement moins gourmand en mémoire, bien sur on parle de pas grand chose mais voila.
J'avais lu une étude qui produisait plus ou moins le même résultat (variable suivant la version de PHP entre autres).
Vu la différence, on est dans le domaine de la micro-optimisation.

Mon avis sur la micro-optimisation en général : si on en arrive à essayer de grapiller des micro-secondes/octets de mémoire, c'est qu'il y a un problème de conception :mrgreen:

De plus, vu le peu de différences (et sachant que cette différence joue en faveur de l'un ou de l'autre suivant les versions de PHP), je privilégie la lisibilité.
Et de ce point de vue, je trouve le foreach plus clair. Donc...

Re: Style de codage

par devlop78 » 20 sept. 2011, 17:28

unset($tab[5]);
Un E_NOTICE + 1 null + le dernier oublié

Re: Style de codage

par devlop78 » 20 sept. 2011, 17:27

Pour être valable sur tous les types de tableaux on peut taper sur next() etc pour le while :

while ($a = next($machin))
{

}

Comme ça il avance le curseur sans se préoccuper de la suite numérique.
J'ai rajouté le while augmenter la ram le nombre d'occurences et un coup de shuffle
<?php

ini_set('memory_limit', '1024M');
$truemem = false;

$tab = array();

for($i=0; $i<250000; $i++) {
	array_push($tab, $i);
}
shuffle($tab);

$var = '';
$t1 = microtime(true);
$m1 = memory_get_usage($truemem);
$ct = count($tab);
for($i=0; $i<$ct; $i++) {
	$var = $i . $tab[$i];
}
$t2 = microtime(true);
$m2 = memory_get_usage($truemem);
$diff1 = $t2 - $t1;
$mdiff1 = $m2 - $m1;

$var = '';
$t1 = microtime(true);
$m1 = memory_get_usage($truemem);
foreach($tab as $num=>$i) {
	$var = $num . $i;
}
$t2 = microtime(true);
$m2 = memory_get_usage($truemem);
$diff2 = $t2 - $t1;
$mdiff2 = $m2 - $m1;

$var = '';
$t1 = microtime(true);
$m1 = memory_get_usage($truemem);
$ct = count($tab);
$i=0;
while($i < $ct) {
	$var = $i . $tab[$i];
	$i++;
}
$t2 = microtime(true);
$m2 = memory_get_usage($truemem);
$diff3 = $t2 - $t1;
$mdiff3 = $m2 - $m1;

echo 'for time: '.$diff1.''."\n";
echo 'for mem: '.$mdiff1.''."\n";
echo 'foreach time: '.$diff2.''."\n";
echo 'foreach mem: '.$mdiff2.''."\n";
echo 'while time: '.$diff3.''."\n";
echo 'while mem: '.$mdiff3.''."\n";
for time: 0.10704684257507
for mem: 632
foreach time: 0.093402862548828
foreach mem: 136
while time: 0.1063129901886
while mem: 88
avantage à foreach, mais pas un gros avantage, je vais voir si je peut trouver un cas ou le foreach est moins bon, en jouant sur ce qui se passe à l'intérieur des boucles.

Re: Style de codage

par devlop78 » 20 sept. 2011, 17:24

Je réaffirme deux choses : Il est rare de se battre pour si peu de différence alors même que tu itères sur 250 000 items. Et de deux, ce n'est pas adapté aux tableaux associatifs ou à trous.

Mais, parce que avec moi il y a toujours un mais (c'est bon l'auto-dérision), c'est toujours bien à savoir, et ça peut aider sur des cas particuliers d'algorithme.

Essai avec une modification au moins une fois dans le for() et foreach() pour provoquer le copy on write de php. Je pense que la différence sera encore plus flagrande.
Petit benchmark
<?php

$tab = array();

for($i=0; $i<250000; $i++) {
	array_push($tab, $i);
}

$var = '';
$t1 = microtime(true);
$m1 = memory_get_usage();
$ct = count($tab);
for($i=0; $i<$ct; $i++) {
	$var .= $i;
}
$t2 = microtime(true);
$m2 = memory_get_usage();
$diff1 = $t2 - $t1;
$mdiff1 = $m2 - $m1;

$var = '';
$t1 = microtime(true);
$m1 = memory_get_usage();
foreach($tab as $i) {
	$var .= $i;
}
$t2 = microtime(true);
$m2 = memory_get_usage();
$diff2 = $t2 - $t1;
$mdiff2 = $m2 - $m1;

echo 'for time: '.$diff1.''."\n";
echo 'for mem: '.$mdiff1.''."\n";
echo 'foreach time: '.$diff2.''."\n";
echo 'foreach mem: '.$mdiff2.''."\n";
Mes résultats sont sensiblement constants un exemple de résultat serait:
for time: 0.03811502456665
for mem: 1389512
foreach time: 0.040256023406982
foreach mem: 1388808
Ce qui montre que le for est plus rapide que le foreach, en revanche le foreach est effectivement moins gourmand en mémoire, bien sur on parle de pas grand chose mais voila.