Style de codage

ViPHP
xTG
ViPHP | 7331 Messages

18 sept. 2011, 19:25

Gnagnagnagna ! Stealth comme toujours tu te caches mais quand tu te montres ça explose ! =D>
Une bonne astuce que j’apprends aujourd’hui en PHP.

ViPHP
AB
ViPHP | 5818 Messages

18 sept. 2011, 20:26

je ferais surtout
if ( !isset($a, $b) ) { }
cela ne correspond pas aux conditions énoncées par Berzemus mais à
if ( !isset($a) || !isset($b) ) {  }

ViPHP
ViPHP | 4039 Messages

18 sept. 2011, 21:05

comme le suggère AB, l'utilisation du isset était à titre d'illustration... enfin soit, ça aura permis de présenter une subtilité PHP de plus :roll:
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

ViPHP
ViPHP | 5462 Messages

19 sept. 2011, 02:59

je ferais surtout
if ( !isset($a, $b) ) { }
cela ne correspond pas aux conditions énoncées par Berzemus mais à
if ( !isset($a) || !isset($b) ) {  }
en effet ça rend pas la même chose :wink:

Mammouth du PHP | 672 Messages

19 sept. 2011, 14:36

J'avoue que là, avec la tonne d'indentation, il est quasiment impossible de le respecter :
(...)
Je veux bien sauter des lignes, mais un moment ça devient lourd ... On a déjà 93 caractères sur la grande ligne, il faudrait séparer la concaténation, la liste de l'array, etc ...
Enfin il ne faut pas non plus exagérer, hein...
Il ne s'agit pas de se fixer des contraintes là où il n'y en a pas. Juste de se fixer un cadre de conduite.

Et, en programmation comme en français, limiter la longueur des "phrases" permet de mieux organiser la pensée (je trouve).

devlop78
Invité n'ayant pas de compte PHPfrance

19 sept. 2011, 15:14

Oui, c'est certain. Là je me prends surtout la tête sur la modélisation (au sens large).

D'ailleurs, je pense que je ne vais pas tarder à remettre la tête dans la doc Zend Framework pour respecter à la lettre leurs recommandations. Je ne suis pas loin quand même ;)

Aller. Un petit tour (au hasard) :
        if ($application->hasOption('resourceloader')) {
            $this->setOptions(array(
                'resourceloader' => $application->getOption('resourceloader')
            ));
        }
versus
defined('APPLICATION_PATH')
    || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));
Je trouve les codes sources intéressantes à analyser (à coté ce qui est en haut est un troll), par exemple du bon emploi des fonctions php (et globales aux langages souvent) :
        $return = $this->getPrefix()
                . implode($this->getSeparator(), $items)
                . $this->getPostfix();
Là où on serait tenté de (en tous cas, moi j'avoue) :
$return = "<ul><li>";
foreach ($items as $item)
{
   $return .= $item . '</li><li>';
}
$return = substr($return,0,-4);
$return .= (count($items) > 0 ? '</li>' : '') . </ul>';
Là dans leur cas, c'est quand même plus simple ... Si ce n'est (le détail) que si $items est vide, il y aura un <li></li> vide. Mais est-ce si important ... Si à côté on a une structure globalement en charpie ... ;)

ViPHP
ViPHP | 2577 Messages

20 sept. 2011, 09:49

Leur code est mieux en dehors du tableau vide que l'on doit traiter à part avant l'appel.

Je préfère une version avec un test sur le tableau et 2 affectations en fonction du cas.

ViPHP
ViPHP | 3300 Messages

20 sept. 2011, 11:47

faut pas oublier aussi que foreach c'est mal, c'est la pire des solutions pour boucler, en fait à moins que les perfs ne soient pas un point qui t'intéresse faudrait jamais utiliser foreach mais lui préférer for ou encore mieux while... bon après dans ce cas précis implode c'est le top, parce que c'est ce que tu veux faire, une boucle ici ça se justifie uniquement quand on ne sait pas que implode existe :)
Fait du php depuis que ca existe ou presque :)

Eléphant du PHP | 275 Messages

20 sept. 2011, 14:51

Au contraire, foreach c'est le bien, en particulier si tu dois itérer sur TOUS les éléments d'une liste.

ViPHP
ViPHP | 3300 Messages

20 sept. 2011, 15:10

Au contraire, foreach c'est le bien, en particulier si tu dois itérer sur TOUS les éléments d'une liste.
il est ou l'argument? bon je t'explique pourquoi foreach c'est mal: foreach crée une variable à chaque tour de boucle, ce que ne font ni for ni while le résultat c'est que tu va occuper en mémoire exactement le double avec foreach, quand on sait qu'une affectation mémoire c'est ce qu'il y a de plus coûteux en programmation on en déduit que foreach est le pire système de bouclage (le plus lent, le moins performant), maintenant je crois que ton argument c'est que foreach boucle systématiquement sur tous les éléments d'une structure de données tubulaire, est ce que tu crois qu'on ne peut pas le faire avec un for ou un while?
Fait du php depuis que ca existe ou presque :)

Eléphant du PHP | 275 Messages

20 sept. 2011, 15:17

1) foreach boucle sur tous les éléments avec leur clef
2) foreach se base en effet sur une copie du tableau initial, ce qui ne coûte rien grâce au copy-on-write
3) foreach est la boucle la plus rapide pour parcourir une liste ou un tableau

Pour rire, essayes de parcourir une liste dans son intégralité avec un for.

devlop78
Invité n'ayant pas de compte PHPfrance

20 sept. 2011, 16:12

Je suis d'accord avec le COW, mais il est vrai qu'une petite partie de mémoire contient des symboles (mais pas de Zval). Dans le cas d'une boucle, il y a quand même $i (par exemple). Mais la question n'est même pas là. Php utilise les tableaux numériques comme des tableaux associatifs. Il ne fait apparemment pas la distinction. J'ai fait des bench, et rien ne le dérange dans les trous que l'on peut trouver dans les tableaux. Et, à moins de considérer un tableau comme une pile, beaucoup de tableaux possèdent des trous, donc un for() n'aura pas de sens. Un while, davantage. Mais est-ce que un while() fonctionne sur un objet qui implémente un itérateur ? C'est possible, mais pas sûr. Toujours utile que le foreach() est précisemment conçu pour itérer. Et il a un comportement légèrement différent d'un while(next() ..), entre autres : il travaille sur une "copie" (en fait les données d'origine tant que ni l'origine ni la copie n'est modifiée), ce qui fait qu'aucune action sur le tableau d'origine ne le dérange (contrairement à d'autres langages).

Il faut aussi arrêter de parler de perf à tout va, alors que l'on travaille souvent avec des frameworks, et que l'on montre les ORM des fois comme des dieux.

Un peu lourd, mais voilà le résultat de quelques tests (pas forcément lié à la conversion, mais plus ou moins étonnants) :

Code : Tout sélectionner

Démarrage avec 25000 éléments Je confirme avoir été témoin de 20000 instructions de début de tableau avec unset() en 0.04050 secondes. Nombre d'élements restants avec count : 5000 Démarrage avec 25000 éléments Je confirme avoir été témoin de 20000 instructions de début de tableau avec array_shift() en 4.50380 secondes. Nombre d'élements restants avec count : 5000 Démarrage avec 25000 éléments Je confirme avoir été témoin de 20000 instructions de fin de tableau avec unset() en 0.01950 secondes. Nombre d'élements restants avec count : 5000 Démarrage avec 25000 éléments Je confirme avoir été témoin de 20000 instructions de fin de tableau avec array_pop() en 0.08520 secondes. Nombre d'élements restants avec count : 5000 Démarrage avec 25000 éléments Je confirme avoir été témoin de 20000 instructions de milieu de tableau avec unset() en 0.01590 secondes. Nombre d'élements restants avec count : 5000 Démarrage avec 25000 éléments Je confirme avoir été témoin de 20000 instructions de milieu de tableau avec array_splice() (suppression) en 52.04460 secondes. Nombre d'élements restants avec count : 5000 Démarrage avec 5000 éléments Je confirme avoir été témoin de 20000 instructions de fin de tableau avec array_push() en 0.08500 secondes. Nombre d'élements restants avec count : 25000 Démarrage avec 5000 éléments Je confirme avoir été témoin de 20000 instructions de fin de tableau avec [] en 0.01950 secondes. Nombre d'élements restants avec count : 25000 Démarrage avec 5000 éléments Je confirme avoir été témoin de 20000 instructions de fin de tableau avec [$i] en 0.01960 secondes. Nombre d'élements restants avec count : 25000 Démarrage avec 5000 éléments Je confirme avoir été témoin de 20000 instructions de début de tableau avec array_unshift() en 62.30800 secondes. Nombre d'élements restants avec count : 25000 Démarrage avec 5000 éléments Je confirme avoir été témoin de 20000 instructions de début de tableau avec array_splice() (ajout) en 71.43780 secondes. Nombre d'élements restants avec count : 25000 Démarrage avec 5000 éléments Je confirme avoir été témoin de 20000 instructions de milieu de tableau avec array_splice() (ajout) en 76.14350 secondes. Nombre d'élements restants avec count : 25000 Démarrage avec 5000 éléments Je confirme avoir été témoin de 20000 instructions de fin de tableau avec array_splice() (ajout) en 74.50060 secondes. Nombre d'élements restants avec count : 25000

Code : Tout sélectionner

Résultats à peu près similaires à plusieurs essais Test de mémoire de tableaux dont des éléments ont été supprimés : tableaux recomposés et tableaux bruts Iteration initiale (nombre d'elements : 25000) Temps d'itération : 0.00670 Suppression de 10000 éléments avec unset() Iteration après suppression (nombre d'élements : 15000) Temps d'itération : 0.00390 Reorganisation du tableau Iteration après réorganisation (nombre d'élements : 15000) avec array_values Temps d'itération : 0.00420

ViPHP
ViPHP | 3300 Messages

20 sept. 2011, 16:59

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.
Fait du php depuis que ca existe ou presque :)

Eléphant du PHP | 275 Messages

20 sept. 2011, 17:06

Et tu pars du principe que ta liste est indexée correctement :]

ViPHP
ViPHP | 3300 Messages

20 sept. 2011, 17:14

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.
Fait du php depuis que ca existe ou presque :)