Précédent   Forum du club des développeurs et IT Pro > PHP > Langage
Langage Forum sur le langage PHP, la POO, les conventions, la sécurité, etc. Avant de poster : FAQ Langage, toutes les FAQ PHP, cours langage et sources PHP
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Actualité déjà publiée
 
Outils de la discussion
Publicité
'
Vieux 05/04/2007, 13h20   #61
Djakisback
Membre Expert
 
Avatar de Djakisback
 
Inscription : février 2005
Messages : 1 910
Détails du profil
Informations forums :
Inscription : février 2005
Messages : 1 910
Points : 1 839
Points : 1 839
Ca dépend également de l'architecture matérielle, si par exemple ton SGBD n'est pas sur la même machine que PHP, tu peux avoir envie de déléguer des tâches au middleware afin de préserver les ressources de la machine du SGBD. Mais c'est plutôt dans le cas de lourds traitements SQL et non de jointures.
Djakisback est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/04/2007, 14h25   #62
sekaijin
Expert Confirmé Sénior
 
Avatar de sekaijin
 
Homme
Urbaniste
Inscription : juillet 2004
Messages : 2 116
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 49
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Urbaniste
Secteur : Santé

Informations forums :
Inscription : juillet 2004
Messages : 2 116
Points : 5 034
Points : 5 034
non non non non

quoi qu'il arrive indexé ou pas tables mal foutues
machine locale machine distante

un en semble de jointure est toujours toujours beaucoup beaucoup plus performant que tous les les while et autre moyen d'y arriver pour faire ça coté application.

c'est totalement incomparable.

maintenant si tu veux optimiser il te faut user du explain pour pas faire tes jointure n'importe comment
la longueur et la largeur de chaque ensemble join est important
la position des index sur les tables aussi
les contrainte dans la requête aussi

une fois ta requête correcte tu peux toujours essayer de faire des boucles en php pour assurer tes jointures tu n'arrivera jamais à la hauteur de la plus mauvaise façon d'exécuter tes jointures en SQL

le problème qui peut arriver est celui de la taille
par exemple si j'ai des clients qui ont un panier (liste de produits)
si je récupère tous mes clients qui font chacun 5Ko
qu'ils ont tous dans leur panier 10 produits pesant chacun 3Ko
chaque client représente un espace mémoire 5Ko+ 10x3Ko = 35Ko
pour 1 000 000 de client cela représente 35 000 000 Ko mais aussi
1 000 001 requêtes sur la base
en faisant la jointure en php
en la faisant en SQL
j'ai 1 requête
mais pour chaque produit de chaque client j'ai
3Ko+5Ko = 8Ko soit donc
80 000 000 Ko et non plus 35 000 000 Ko

je le répète ce sera de toute façon beaucoup plus rapide. mais il faut faire attention à la largeur et la longueur de chaque élément car une jointure c'est un produit cartésien au sens mathématique c'est bien un produit et pas une somme

il y a donc un risque de saturer ton application
mise à par cela n'hésite pas à faire des jointures.

et plus tu en feras plus tu maitriseras SQL plus elle seront effilasses.

un dernier point une requête n'est jamais optimale. et ne l'est que dans le contexte d'exécution du moment ou on l'optimise. avec la vie de la base une requête effilasse peut devenir catastrophique et une requête peut performante se montrer très rapide. de même sur les index un index peut être utile à un moment dans la vie de l'application et une charge à un autre.
c'est pour cela qu'existe le métier de DBA.

A+JYT
sekaijin est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/04/2007, 14h53   #63
Djakisback
Membre Expert
 
Avatar de Djakisback
 
Inscription : février 2005
Messages : 1 910
Détails du profil
Informations forums :
Inscription : février 2005
Messages : 1 910
Points : 1 839
Points : 1 839
Personnellement, je parlais de lourds traitements comme des formatages de champs, calcul, regex, etc, et non des jointures qui seront certainement plus rapides sur le SGBD (sans parler du cache), des fois il vaut mieux utiliser les fonctions du middleware que celles du SGBD. De toute façon vu que l'optimisation c'est du cas par cas...
Djakisback est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/04/2007, 14h45   #64
ilhooq
Futur Membre du Club
 
Inscription : décembre 2005
Messages : 11
Détails du profil
Informations personnelles :
Âge : 33
Localisation : France, Loire (Rhône Alpes)

Informations forums :
Inscription : décembre 2005
Messages : 11
Points : 18
Points : 18
Citation:
Envoyé par fadex
Bonjour

Code le plus rapide :
Code :
1
2
3
4
5
$count = count($array);
for ($i=0; $i<$count; $i++)
{
  echo $array[$i];
}
merci d'avance
Est ce que la construction foreach serait plus lente?

Code :
1
2
 
foreach ($array as $v) echo $v;
ilhooq est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/04/2007, 17h08   #65
ilhooq
Futur Membre du Club
 
Inscription : décembre 2005
Messages : 11
Détails du profil
Informations personnelles :
Âge : 33
Localisation : France, Loire (Rhône Alpes)

Informations forums :
Inscription : décembre 2005
Messages : 11
Points : 18
Points : 18
Citation:
Envoyé par haltabush
Je pense que oui, puisque tu fais une affectation à chaque boucle, ce qui n'est pas nécessaire avec une boucle for.
Oui en effet il y'a une affectation à chaque boucle mais d'un autre côté l'affectation se fait en interne avec foreach. Cela dit, pour vérifier, j'ai réalisé cette expérience et un coup sur deux foreach est plus rapide... (sous win xp, PHP 5.1):
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 
<?php
 
function microtime_float() 
{
  list($usec, $sec) = explode(" ", microtime());
  return ((float)$usec + (float)$sec);
}
 
 
function showTimeExec($timeStart,$msg)
{ 
    $time_end = microtime_float();
    $time_exec = $time_end - $timeStart ;
    echo " $msg : <strong> $time_exec </strong> <br />\n";
}
 
//remplissage du tableau
$array =  array();
for ($i=0; $i < 9000 ; $i++) {
    $array[] = $i;
}
 
//test for
 
$timeStart1 = microtime_float() ;
 
$count = count($array);
for ($i=0; $i<$count; $i++)
{
  echo $array[$i] .' ; ';
}
showTimeExec($timeStart1, ' temps d\'execution boucle for');
 
//test foreach
 
$timeStart2 = microtime_float() ;
 
foreach ($array as $v) {
    echo $v .' ; ' ;
}
 
showTimeExec($timeStart2, ' temps d\'execution boucle foreach');
 
?>
Il faudrait tester ce bout de code sur d'autres environnements pour voir...

Bon et même si foreach peu s'avérer être légèrement plus lent, je trouve son utilisation dans certaines conditions plus élégante (genre pour boucler sur un tableau de 50 résultats )
ilhooq est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/04/2007, 17h20   #66
haltabush
Membre émérite
 
Avatar de haltabush
 
Développeur Web
Inscription : avril 2005
Messages : 726
Détails du profil
Informations personnelles :
Âge : 28
Localisation : France

Informations professionnelles :
Activité : Développeur Web

Informations forums :
Inscription : avril 2005
Messages : 726
Points : 822
Points : 822
De mon coté, avec Xp, Apache2.0.59 et PHP 5.2.0 (WAMP version 1.6.6), j'ai un temps d'exécution de 5 à 10 fois plus rapide avec le for ^^
__________________
HADOPI : black-out du net!
haltabush est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/04/2007, 18h04   #67
ilhooq
Futur Membre du Club
 
Inscription : décembre 2005
Messages : 11
Détails du profil
Informations personnelles :
Âge : 33
Localisation : France, Loire (Rhône Alpes)

Informations forums :
Inscription : décembre 2005
Messages : 11
Points : 18
Points : 18
Perso sur ma config (WinXp+PHP5.1.6+APACHE2.0.59+Zend optimizer), j'ai testé le code plus haut sur un tableau de 100 000 clés j'ai pour résultat:

for : 0.261 sec
foreach: 0.242 sec

Peut-être que c'est Zend optimizer qui fait la différence mais quand tu dis que for est 5 a 10 fois plus rapide ça me semble curieux : ça voudrait dire qu'avec foreach tu mettrais 2.42 sec. As tu testé le code?
ilhooq est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/04/2007, 10h00   #68
sekaijin
Expert Confirmé Sénior
 
Avatar de sekaijin
 
Homme
Urbaniste
Inscription : juillet 2004
Messages : 2 116
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 49
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Urbaniste
Secteur : Santé

Informations forums :
Inscription : juillet 2004
Messages : 2 116
Points : 5 034
Points : 5 034
Citation:
Envoyé par haltabush
Je pense que oui, puisque tu fais une affectation à chaque boucle, ce qui n'est pas nécessaire avec une boucle for.
non il n'y a pas d'affectation dans la boucle foreach
Code :
1
2
foreach ($tab as $key => $value) {
}
à chaque itération calcul de l'index $key
calcule de l'@dresse de $tab + $key placement de cette adress dans $value
(il n'y aura copie que si c'est necessaire le compilateur optimise ce genre d'accès)

alor que dans le for
dans tu calcule l'index $i puis l'adresse $tab + $i et tu passe cette adresse à echo

la différence est donc l'affectation d'un int dans une case memoire. et je ne serais pas surpris de voir que si cette adresse n'est utilisé que pour le écho le compilateur optimise ça.

une note au passage
quelque soit la methode utilisé un Tableau PHP n'est pas un Tableau C bref les élément ne sont pas rangé dans des case contigues. ce sont des Htable et dans tout les cas il y a une indirection sur les index.
en C l'adresse de l'élément i est @dresse de tab+(i x taille enregistrement)
dans une HTable les élément sont placé n'importe où dans le tas (memoire) uun tableau d'index contient la liste des adresses de ces éléments.
A+JYT
sekaijin est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/04/2007, 21h33   #69
ilhooq
Futur Membre du Club
 
Inscription : décembre 2005
Messages : 11
Détails du profil
Informations personnelles :
Âge : 33
Localisation : France, Loire (Rhône Alpes)

Informations forums :
Inscription : décembre 2005
Messages : 11
Points : 18
Points : 18
Merci pour ces explications pointues.

Par rapport aux tests plus haut entre for et foreach, une chose m'a frappé: tantôt foreach est plus rapide, tantôt for est plus rapide (sur des centièmes de secondes). Comment expliquer ce comportement? C'est les caractéristiques des HTables qui provoquent cela?

Sinon pour en revenir au sujet du débat, si foreach equivaut en rapidité avec for pour parcourir un tableau alors il est plus pertinent de l'utiliser car c'est sa fonction. De plus, on y gagne en clarté au niveau du code.
ilhooq est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/04/2007, 12h55   #70
Djakisback
Membre Expert
 
Avatar de Djakisback
 
Inscription : février 2005
Messages : 1 910
Détails du profil
Informations forums :
Inscription : février 2005
Messages : 1 910
Points : 1 839
Points : 1 839
Pour faire des tests plus fiables il faut faire 2 scripts distincts et non juste mettre les appels à la suite et juger sur des itérations/tableaux beaucoup plus grands. Foreach travaillant sur une copie du tableau (ou des valeurs) il y a de fortes chances qu'il soit plus lent.
Djakisback est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/04/2007, 15h03   #71
ilhooq
Futur Membre du Club
 
Inscription : décembre 2005
Messages : 11
Détails du profil
Informations personnelles :
Âge : 33
Localisation : France, Loire (Rhône Alpes)

Informations forums :
Inscription : décembre 2005
Messages : 11
Points : 18
Points : 18
Citation:
Envoyé par Djakisback
Foreach travaillant sur une copie du tableau (ou des valeurs) il y a de fortes chances qu'il soit plus lent.
Depuis PHP5 foreach peut assigner par référence:

Code :
1
2
3
4
5
6
7
8
 
<?php
$arr = array(1, 2, 3, 4);
foreach ($arr as &$value) {
    $value = $value * 2;
}
// $arr vaut maintenant array(2, 4, 6, 8)
?>
ilhooq est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/05/2007, 22h13   #72
spidermario
Membre émérite
 
Étudiant
Inscription : septembre 2006
Messages : 510
Détails du profil
Informations personnelles :
Âge : 19

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : septembre 2006
Messages : 510
Points : 905
Points : 905
Citation:
Envoyé par Shinuza
Etonnant que personne n'ai corrigé ça :

Code :
echo 'Bonjour,' , $pseudo , 'Ca va?';
Echo est une instruction, de ce fait le fait d'utiliser des points revient à avoir deux fois echo pour afficher la chaine séparée de la variable. Alors que la virgule permet de tout faire d'un coup.
Là, tu te trompes, c'est carrément l'inverse :
Le point concatène la chaîne, ce qui fait qu'elle est stockée en mémoire puis envoyée,
tandis que la virgule écrit plusieurs fois de suite sur le flux de sortie.

Après, quant aux conséquences sur les performances, ça dépend de plusieurs choses, comme le fait d'écrire directement sur le flux de sortie ou sur un tampon (par exemple avec ob_start()).
spidermario est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/05/2007, 21h58   #73
sekaijin
Expert Confirmé Sénior
 
Avatar de sekaijin
 
Homme
Urbaniste
Inscription : juillet 2004
Messages : 2 116
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 49
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Urbaniste
Secteur : Santé

Informations forums :
Inscription : juillet 2004
Messages : 2 116
Points : 5 034
Points : 5 034
ne jamais écrire sur la sortie et la question des perfs ne se pose pas

1 point d'entré 1 point de sortie
pour un script pour une fonction
cela reste toujours valable. c'est un gage d'évolutivité et de clarté pour la maintenance

A+JYT
sekaijin est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/05/2007, 09h37   #74
Shinuza
Membre éclairé
 
Inscription : novembre 2006
Messages : 336
Détails du profil
Informations forums :
Inscription : novembre 2006
Messages : 336
Points : 320
Points : 320
Citation:
Envoyé par spidermario
Là, tu te trompes, c'est carrément l'inverse :
Le point concatène la chaîne, ce qui fait qu'elle est stockée en mémoire puis envoyée,
tandis que la virgule écrit plusieurs fois de suite sur le flux de sortie.

Après, quant aux conséquences sur les performances, ça dépend de plusieurs choses, comme le fait d'écrire directement sur le flux de sortie ou sur un tampon (par exemple avec ob_start()).
Faux.
Utilisé avec avec des virgules echo se comporte comme une fonction, et reçoit ainsi plusieurs paramètres qui sont envoyés au tampon de sortie sous la forme d'une seule chaine.
Avec des points on crée autant d'objets en mémoire que de littéraux.

J'ai fais du profiling des deux méthodes, la troisième méthode étant de mettre la totalité dans une variable et de l'afficher ensuite, ça mets jusqu'à 10 fois plus longtemps sur l'affichage d'un ko de texte.

La différence est minime mais la virgule est plus stable et souvent plus rapide.

Citation:
Envoyé par Korko Fain
et comme tous, echo pouvant etre assimilé à une fonction, il faut lui mettre des ().
Comme je l'ai dis, echo est assimilé à une fonction uniquement lorsqu'on l'utilise avec des virgules.
Shinuza est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/05/2007, 11h49   #75
Fladnag
Membre Expert
 
Homme
Inscription : janvier 2004
Messages : 1 241
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Secteur : Finance

Informations forums :
Inscription : janvier 2004
Messages : 1 241
Points : 1 426
Points : 1 426
Bon... avant de dire des betises, ca serait bien de faire l'effort d'aller voir au moins la page de la documentation officielle de la "fonction" echo.

Et là, on voit, dès la premiere ligne, que "echo() n'est pas vraiment une fonction" ce qui permet justement de s'affranchir des parentheses, qui sont sinon obligatoires pour toutes fonctions.

Pour tout ce qui est de la performance d'un code par rapport a un autre, il est tres simple pour chacun de faire ses benchmark dans son coin (meme si ca serait bien que ce soit centralisé...) afin de comparer les temps d'execution de chaque cas.
Pour cela, il faut faire varier :
* Les environnements (PHP4, PHP5, avec ou sans Zend, etc...)
* La taille des structures traitées (un tableau ne se comportera pas de la meme maniere avec 10 ou avec 100000 elements lors d'un parcours de boucle)
* La taille des données traitées (un tableau de 10 elements avec 1000Ko dans chaque element ce n'est pas pareil non plus qu'un tableau avec 10000 elements d'1Ko)
* etc...

pour le echo en question, il faudrait tester avec N parametres, n variant entre 1 et 1000 par exemple, dans un boucle d'au moins 1000 ou 10000 iterations, sur un environnement stable sans programme en tache de fond qui viendrait "polluer" le test.
Fladnag est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/05/2007, 12h01   #76
Korko Fain
Membre chevronné
 
Avatar de Korko Fain
 
Étudiant
Inscription : août 2005
Messages : 632
Détails du profil
Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : août 2005
Messages : 632
Points : 661
Points : 661
if, else, elseif, while, for tout ceci ne sont pas des fonctions et pourtant pour une question de lisibilité, on met toujours des parentheses, c'est une erreur à mon gout de faire une exception pour la procedure echo.

En effet, entre echo( 'tralal', 'toto'); et echo 'tralala' . 'toto';
Les 2 fonctionnent mais il est BEAUCOUP plus facile de faire une erreur si on met une virgule au lieu d'un point et qu'on n'a pas mis les parentheses. Et pour un néophyte, c'est plus facilement compréhensible d'écrire echo() que echo.

Cette façon d'écrire sans parentheses c'est du shell.
Korko Fain est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/05/2007, 13h39   #77
Fladnag
Membre Expert
 
Homme
Inscription : janvier 2004
Messages : 1 241
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Secteur : Finance

Informations forums :
Inscription : janvier 2004
Messages : 1 241
Points : 1 426
Points : 1 426
encore non.

if then else for while sont des structures du langages et là, les parentheses sont OBLIGATOIRES !

ne fonctionne pas en php (tu m'a fait douter, mais apres un test, je confirme bien !)

seule la "fonction" echo peut s'en passer. et contrairement a ce que tu penses, la lisibilité n'est pas déterminée par les parentheses... (regarde le langage LISP ;o)

je prefere 100 fois un code du genre :

Code :
1
2
3
if ($truc) {
   echo 'Le resultat est ',(($val*100)/2)*($coeff*ponderation);
}
à :

Code :
1
2
3
if ($truc) {
   echo ('Le resultat est ',(($val*100)/2)*$coeff*ponderation));
}
Les parentheses alourdissent TOUJOURS le code, elles n'aident a la lisibilité que lorsqu'elles permettent de résoudre facilement les regles de priorité dans une expression booleene. $a && $b || $c est illisible, meme si le resultat est exact, ca suppose pour relire le code de connaitre par coeur la priorité des operateurs. Dans ce cas là je suis pour l'utilisation de parentheses... mais sinon... autant s'en passer. Ce ne sont que des "bruits" du langage (= des elements syntaxiques n'apportant absoluement rien) dans la plupart des cas.
Fladnag est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 06/05/2007, 17h05   #78
Korko Fain
Membre chevronné
 
Avatar de Korko Fain
 
Étudiant
Inscription : août 2005
Messages : 632
Détails du profil
Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : août 2005
Messages : 632
Points : 661
Points : 661
Je préfaire 100 fois la deuxieme syntaxe et presque tous les codeurs que je connais de visu préfaire avec des parentheses mais bon c'est une question de gout. Je n'aime pas faire une exception sur tout un langage pour 1 cas très rare.
Korko Fain est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/05/2007, 10h58   #79
sekaijin
Expert Confirmé Sénior
 
Avatar de sekaijin
 
Homme
Urbaniste
Inscription : juillet 2004
Messages : 2 116
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 49
Localisation : France, Yvelines (Île de France)

Informations professionnelles :
Activité : Urbaniste
Secteur : Santé

Informations forums :
Inscription : juillet 2004
Messages : 2 116
Points : 5 034
Points : 5 034
Citation:
Envoyé par Fladnag
B...Regle n°1 : mysql_query(...), mysql_connect(...) et mysq_select_db(...) doivent etre suivies de or die(mysql_error());
Regle n°2 : Mieux encore : mysql_query($requete) or die("$requete<br/>".mysql_error());
Regle n°3 : echo '<pre>';var_dump($var);echo '</pre>'; affiche le contenu et le type d'une variable : Pratique pour debugger
Regle n°4 : RTFM !!!
Regle n°5 : dites NON au langage SMS...
NON à la règle 1 car l'utilisateur n'a pas à se retrouve brutalement avec des script moitié fini
IL faut au contraire traiter l'erreur et rendre la chose inéligible
NON à la règle 2 pour les même raison
la règle N° 3 devrait être les seule sortie en cours de code qu'on devrait trouver dans un programme.

A+JYT
sekaijin est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/05/2007, 11h03   #80
Korko Fain
Membre chevronné
 
Avatar de Korko Fain
 
Étudiant
Inscription : août 2005
Messages : 632
Détails du profil
Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : août 2005
Messages : 632
Points : 661
Points : 661
Surtout que pour n'importe quel pirate, avoir une erreur sql avec le détails de la requete est une source inespérée d'informations qui peux poser un gros probleme. En effet, lors d'un test d'injection SQL, le fait d'afficher la requete montre au pirate comment à réagi le serveur et le script php à son attaque et donc lui indique comment proceder. Non il ne faut JAMAIS (hors debug) faire un die en dur comme ça. Il faut traiter les cas d'erreur et afficher un message personnalisé "Impossible d'effectuer la requete n°..." par exemple. Et pas le code de la requete en elle meme.
Korko Fain est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Actualité déjà publiée
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 18h34.


 
 
 
 
Partenaires

Hébergement Web