IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Optimisation de code


Sujet :

Langage PHP

  1. #1
    Membre éclairé
    Avatar de clavier12AZQSWX
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2009
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 414
    Points : 871
    Points
    871
    Par défaut Optimisation de code
    Bonjour,

    je suis en train d'optimiser un énorme code PHP, brassant et factorisant énormément de tableaux de grosse taille (150x200).

    Ma méthode première est de modifier les erreurs de code de jeunesse comme les abus de count($x) dans des conditions boucle : si $x est un tableau énorme multidimensionnel alors la charge cpu est énorme et c'est stupide de faire ça dans une boucle si la taille de $x ne change jamais dans la boucle!

    Connaissez-vous la liste des fonctions PHP qui sont longues à traiter et qu'il faut extérioriser des conditions bouclables ?

    merci de votre aide.

  2. #2
    Modérateur
    Avatar de sabotage
    Homme Profil pro
    Inscrit en
    Juillet 2005
    Messages
    29 208
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juillet 2005
    Messages : 29 208
    Points : 44 155
    Points
    44 155
    Par défaut
    Bonjour,

    Dans ton exemple ce n'est pas le count() en tant que fonction qui est genant, c'est le fait qu'a chaque tour de boucle il refait la meme chose.
    Le fonction count() en elle meme n'est pas a bannir des boucles.

    Mais tu devrais peut etre commencer par faire un profiling de ton code pour voir réellement ce qui est long et gourmand.
    N'oubliez pas de consulter les FAQ PHP et les cours et tutoriels PHP

  3. #3
    Membre éclairé
    Avatar de clavier12AZQSWX
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2009
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 414
    Points : 871
    Points
    871
    Par défaut ok
    bonjour,

    à titre d'exemple, mon script avec les counts bouclés prenait 135s.
    En passant le count dans une variable avant la boucle et la condition, le script ne prend plus que 25s ! (j'ai un pentium 4 2.5Ghz et 1Gh RAM).
    Par contre je n'ai vu aucun gain de mémoire.

    Comme je l'ai dit, c'est avec des tableaux énormes que l'on voit le gain énorme (et une ptite machine :-) .

    Voilà un exemple du script original non optimisé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    46
    function UpdateChartEntry(&$rs, &$cht_smry, &$xfld, $ybase, $sfld, &$arsfld, $smrytype) {
    	if (is_array($xfld)) { // X = crosstab column field
    		if ($sfld <> "" && is_array($arsfld)) { // Series field
    			for ($i = 0; $i < count($cht_smry); $i++) {
    				for ($j = 1; $j < count($xfld); $j++) {
    					if (trim(strval($cht_smry[$i][0])) == trim(strval($xfld[$j][0])) &&
    						trim(strval($cht_smry[$i][1])) == trim(strval($rs->fields($sfld)))) {
    						$cht_smry[$i][2] = ewrpt_SummaryValue($cht_smry[$i][2], ColVal($rs, $ybase, $j-1), $smrytype);
    					}
    				}
    			}
    			return TRUE;
    		} else { // No series field
    			for ($i = 0; $i < count($xfld)-1; $i++)
    				$cht_smry[$i][2] = ewrpt_SummaryValue($cht_smry[$i][2], ColVal($rs, $ybase, $i), $smrytype);
    			return TRUE;
    		}
    	} elseif ($xfld <> "") { // X = crosstab row field / column field
    		if (is_array($sfld)) { // Column field as series field
    			$ny = count($sfld) - 1;
    			for ($i = 0; $i < count($cht_smry)-1; $i += $ny) {
    				if (trim(strval($cht_smry[$i][0])) == trim(strval($rs->fields($xfld)))) { // Matched
    					for ($j = $i; $j <= $i+$ny-1; $j++)
    						$cht_smry[$j][2] = ewrpt_SummaryValue($cht_smry[$j][2], ColVal($rs, $ybase, $j-$i), $smrytype); // Accumulate Y
    					return TRUE;
    				}
    			}
    		} elseif ($sfld <> "" && is_array($arsfld)) { // Row field as series field
    			for ($i = 0; $i < count($cht_smry); $i++) {
    				if (trim(strval($cht_smry[$i][0])) == trim(strval($rs->fields($xfld))) &&
    					trim(strval($cht_smry[$i][1])) == trim(strval($rs->fields($sfld)))) {
    					AccumCol($rs, $ybase, $cht_smry[$i][2], $smrytype); // Accum Y
    					return TRUE;
    				}
    			}
    		} else { // No series field
    			for ($i = 0; $i < count($cht_smry); $i++) {
    				if (trim(strval($cht_smry[$i][0])) == trim(strval($rs->fields($xfld)))) {
    					AccumCol($rs, $ybase, $cht_smry[$i][2], $smrytype); // Accum Y
    					return TRUE;
    				}
    			}
    		}
    	}
    	return FALSE;
    }
    et voilà le même script optimisé que par les count :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    46
    47
    48
    49
    50
    51
    52
    function UpdateChartEntry(&$rs, &$cht_smry, &$xfld, $ybase, $sfld, &$arsfld, $smrytype) {
    	if (is_array($xfld)) { // X = crosstab column field
    		if ($sfld <> "" && is_array($arsfld)) { // Series field
    			$tmp_count6=count($cht_smry);
    			for ($i = 0; $i < $tmp_count6; $i++) {
    				$tmp_count7=count($xfld);
    				for ($j = 1; $j < $tmp_count7; $j++) {
    					if (trim(strval($cht_smry[$i][0])) == trim(strval($xfld[$j][0])) &&
    						trim(strval($cht_smry[$i][1])) == trim(strval($rs->fields($sfld)))) {
    						$cht_smry[$i][2] = ewrpt_SummaryValue($cht_smry[$i][2], ColVal($rs, $ybase, $j-1), $smrytype);
    					}
    				}
    			}
    			return TRUE;
    		} else { // No series field
    			$tmp_count8=count($xfld)-1;
    			for ($i = 0; $i < $tmp_count8; $i++)
    				$cht_smry[$i][2] = ewrpt_SummaryValue($cht_smry[$i][2], ColVal($rs, $ybase, $i), $smrytype);
    			return TRUE;
    		}
    	} elseif ($xfld <> "") { // X = crosstab row field / column field
    		if (is_array($sfld)) { // Column field as series field
    			$ny = count($sfld) - 1;
    			$tmp_count0=count($cht_smry)-1;
    			for ($i = 0; $i < $tmp_count0; $i += $ny) {
    				if (trim(strval($cht_smry[$i][0])) == trim(strval($rs->fields($xfld)))) { // Matched
    					for ($j = $i; $j <= $i+$ny-1; $j++)
    						$cht_smry[$j][2] = ewrpt_SummaryValue($cht_smry[$j][2], ColVal($rs, $ybase, $j-$i), $smrytype); // Accumulate Y
    					return TRUE;
    				}
    			}
    		} elseif ($sfld <> "" && is_array($arsfld)) { // Row field as series field
    			$tmp_count=count($cht_smry);
    			for ($i = 0; $i < $tmp_count; $i++) {
    				if (trim(strval($cht_smry[$i][0])) == trim(strval($rs->fields($xfld))) &&
    					trim(strval($cht_smry[$i][1])) == trim(strval($rs->fields($sfld)))) {
    					AccumCol($rs, $ybase, $cht_smry[$i][2], $smrytype); // Accum Y
    					return TRUE;
    				}
    			}
    		} else { // No series field
    			$tmp_count=count($cht_smry);
    			for ($i = 0; $i < $tmp_count; $i++) {
    				if (trim(strval($cht_smry[$i][0])) == trim(strval($rs->fields($xfld)))) {
    					AccumCol($rs, $ybase, $cht_smry[$i][2], $smrytype); // Accum Y
    					return TRUE;
    				}
    			}
    		}
    	}
    	return FALSE;
    }

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Février 2007
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 24
    Points : 19
    Points
    19
    Par défaut
    Bonsoir,

    peut-on savoir succinctement les étapes de l'algo utilisé ? A titre de remarque, je vois une variable utilisée dans des tests mais jamais dans le reste du code ($arsfld), peut-être y a t-il des améliorations à apporter sur l'algo lui-même ou sur des tests inutiles. Sinon pour ne pas recalculer les count à chaque passage des boucles, on peut aussi écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for ($i = 0, $size1 = count($arr), $size2 = count($arr2); $i < $size1; $i += $size2)
    après est-ce qu'il y a une best practice à ce sujet...

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Février 2005
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 4
    Points : 6
    Points
    6
    Par défaut
    dans ton code optimisé :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    $tmp_count6=count($cht_smry);
    	for ($i = 0; $i < $tmp_count6; $i++) {
    		$tmp_count7=count($xfld);
    			for ($j = 1; $j < $tmp_count7; $j++) {
    Tu as bien sorti $tmp_count7=count($xfld); de sa boucle ma pas de la première, tu devrais faire ça:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    $tmp_count6=count($cht_smry);
    $tmp_count7=count($xfld);
    	for ($i = 0; $i < $tmp_count6; $i++) {
    		for ($j = 1; $j < $tmp_count7; $j++) {

  6. #6
    Membre éclairé
    Avatar de clavier12AZQSWX
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Avril 2009
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Somme (Picardie)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Avril 2009
    Messages : 1 414
    Points : 871
    Points
    871
    Par défaut
    ok

    pas faux ! même très vrai !
    je vais essayer ! pour voir la différence de perf ...

    je reviendrai donner les résultats

  7. #7
    Membre du Club
    Inscrit en
    Avril 2009
    Messages
    37
    Détails du profil
    Informations forums :
    Inscription : Avril 2009
    Messages : 37
    Points : 40
    Points
    40
    Par défaut
    Tu peux faire mieux sur la meme boucle a priori
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    			$tmp_count6=count($cht_smry);
    			for ($i = 0; $i < $tmp_count6; $i++) {
    				$tmp_count7=count($xfld);
    				for ($j = 1; $j < $tmp_count7; $j++) {
    					if (trim(strval($cht_smry[$i][0])) == trim(strval($xfld[$j][0])) &&
    						trim(strval($cht_smry[$i][1])) == trim(strval($rs->fields($sfld)))) {
    						$cht_smry[$i][2] = ewrpt_SummaryValue($cht_smry[$i][2], ColVal($rs, $ybase, $j-1), $smrytype);
    					}
    				}
    			}
    Effectivement tu peux sortir le count deja, mais sauf erreur de ma part tu peux sortir une grosse partie de ton test.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    			$tmp_count7=count($xfld);
    			for ($i = 0; $i < $tmp_count6; $i++) {
    				if (trim(strval($cht_smry[$i][1])) == trim(strval($rs->fields($sfld)))) {
    					$toto = trim(strval($cht_smry[$i][0]));
    					for ($j = 1; $j < $tmp_count7; $j++) {
    						if ( $toto == trim(strval($xfld[$j][0]))){
    							$cht_smry[$i][2] = ewrpt_SummaryValue($cht_smry[$i][2], ColVal($rs, $ybase, $j-1), $smrytype);
    						}
     
    					}
    				}
    			}
    Cela bien sur si ta fonction ewrpt_SummaryValue ne modifie pas $rs, ni $i, ni cht_smry[$i][0] et [1]

    Tu peux a priori optimiser pas mal sur trim(strval($rs->fields($xfld)) surtout si c'est jamais modifie dans tes differentes fonctions appelées.
    Si c'est modifié forcement tu as moins de marge de manoeuvre ;-)

Discussions similaires

  1. optimiser le code d'une fonction
    Par yanis97 dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 15/07/2005, 08h41
  2. Optimiser mon code ASP/HTML
    Par ahage4x4 dans le forum ASP
    Réponses: 7
    Dernier message: 30/05/2005, 10h29
  3. optimiser le code
    Par bibi2607 dans le forum ASP
    Réponses: 3
    Dernier message: 03/02/2005, 14h30
  4. syntaxe et optimisation de codes
    Par elitol dans le forum Langage SQL
    Réponses: 18
    Dernier message: 12/08/2004, 11h54
  5. optimisation du code et var globales
    Par tigrou2405 dans le forum ASP
    Réponses: 2
    Dernier message: 23/01/2004, 10h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo