Ouverture / fermeture des balises et performances?

91

C'est peut-être une question idiote, mais en tant que personne relativement nouvelle dans PHP, je me demande s'il y a des problèmes de performances liés à l'ouverture et à la fermeture fréquentes des balises PHP dans le code de modèle HTML, et si oui, quelles pourraient être les meilleures pratiques en termes de travailler avec des balises PHP?

Ma question ne porte pas sur l'importance / l'exactitude des balises de fermeture, ou sur le type de code plus lisible qu'un autre, mais plutôt sur la façon dont le document est analysé / exécuté et quel impact cela pourrait avoir sur les performances.

Pour illustrer, considérons les deux extrêmes suivants:

Mélanger les balises PHP et HTML:

<?php echo
   '<tr>
       <td>'.$variable1.'</td>
       <td>'.$variable2.'</td>
       <td>'.$variable3.'</td>
       <td>'.$variable4.'</td>
       <td>'.$variable5.'</td>
   </tr>'
?>
// PHP tag opened once

Séparer les balises PHP et HTML:

<tr>
   <td><?php echo $variable1 ?></td>
   <td><?php echo $variable2 ?></td>
   <td><?php echo $variable3 ?></td>
   <td><?php echo $variable4 ?></td>
   <td><?php echo $variable5 ?></td>
</tr>
// PHP tag opened five times

Serait intéressé d'entendre quelques points de vue à ce sujet, même si c'est juste pour entendre que cela ne fait aucune différence.

Merci.

À M
la source
9
Question intéressante, +1 pour ça. Bien que je ne pense pas que les 2 exemples que vous avez donnés soient la paire idéale pour la comparaison, je comprends l'essentiel :)
okw
Merci ... Il se trouve que je travaille avec une table html massive pour le moment et la question me regarde en quelque sorte ... même si c'est un peu théorique.
Tom
Hors sujet: vous devez utiliser une boucle et un tableau / itérateur de données pour remplir la table.
Decent Dabbler
@fireeyedboy ... bien sûr, je suis d'accord, mais ce n'est pas toujours pratique. Soit nécessite des acrobaties lors de la récupération des données de la base de données, soit la structure HTML ne rentre pas parfaitement dans une boucle.
Tom
4
Je pense que la lisibilité est la chose la plus importante ici. Vous n'allez pas voir d'augmentation / diminution majeure avec quelque chose d'aussi trivial que celui-ci.
Chuck Le Butt

Réponses:

88

3 règles simples pour bien faire les choses:

  • Aucun problème de syntaxe ne peut affecter les performances. La manipulation des données le fait.
  • Parlez de performances uniquement soutenues par les résultats du profilage .
  • L'optimisation prématurée est la racine de tout Mal

Les problèmes de performances sont assez difficiles à comprendre. Il est conseillé aux débutants de ne pas en tenir compte. Parce qu'ils sont toujours impressionnés par des choses insignifiantes et ne voient pas les choses vraiment importantes. Juste par manque d'expérience.

Idem pour votre question. Imaginez que vous obtiendrez jamais une différence. Même le plus gros, disons, une méthode est 2 fois plus rapide. Oh mon Dieu, 2 fois! Je l'ai choisi et j'ai bien optimisé mon application, elle fonctionnera 50% plus vite maintenant!

Faux . Pas 50%. Vous ne remarquerez ni ne mesureriez jamais cette augmentation de vitesse. Parce que vous avez optimisé une partie qui ne prend que 0 0001% de l'exécution totale du script.

Quant aux gros tableaux HTML, cela prend beaucoup de temps au navigateur pour les rendre. Beaucoup plus qu'il n'en fallait pour générer.

Le profilage est un mot clé dans le monde de la performance. On peut éliminer sans aucun doute toute question relative à la performance s'il n'y a pas de mot «profilage». Dans le même temps, le profilage n’est pas sorcier. Je mesure juste le temps d'exécution de différentes parties de votre script. Peut être fait avec un profileur, comme xdebug, ou même manuellement, en utilisant microtime(1). Et seulement après avoir détecté la partie la plus lente, vous pouvez commencer par des tests.

Apprenez à profiler avant de poser des questions sur les performances. Et apprenez à ne pas poser de questions sur les performances s'il n'y a pas de vraies raisons à cela.

L'optimisation prématurée est la racine de tout mal - D.Knuth .

Votre bon sens
la source
4
Pourquoi est-ce si grave que j'utilise le mot «benchmark» au lieu de «profile»? Y a-t-il une différence de sens? J'apprécierais de connaître les différences :)
NikiC
+1 pour citer Donald Knuth et +200 pour une réponse très perspicace.
Clement Herreman
@nikic, Quand est-ce que Col a dit qu'il était mauvais d'utiliser le mot "benchmark" ?? On dirait que vous mettez des mots dans sa bouche ou que vous faites référence à quelque chose au mauvais endroit.
Chuck Le Butt
10
pourquoi est-ce si bien noté? Il ne répond à la question sous aucune forme ou forme. -1 de moi.
bharal
2
@NikiC L'usage habituel dont j'ai été témoin: le benchmarking signifie en quelque sorte mesurer ou classer la performance globale d'un morceau de code afin de le comparer à des solutions alternatives (comme ce qu'Amien a fait dans sa réponse à cette question, ci-dessous), alors que le profilage signifie découvrir quelles parties de votre code sont responsables de tout problème de performance visible par l'utilisateur que vous essayez de résoudre. La différence est que le profilage consiste à déterminer la cause de votre problème de performances, tandis que l'analyse comparative consiste à tester des solutions.
Mark Amery
40

J'ai refait les tests avec 50000 lignes et ajouté la méthode multi-écho en 1 tag aussi

for ($j=0;$j<30;$j++) {
    foreach ($results as $key=>$val){
    ?>
       <tr>
           <td><?php echo $results[$key][0]?></td>
           <td><?php echo $results[$key][1]?></td>
           <td><?php echo $results[$key][2]?></td>
           <td><?php echo $results[$key][3]?></td>
           <td><?php echo $results[$key][4]?></td>
           <td><?php echo $results[$key][5]?></td>
           <td><?php echo $results[$key][6]?></td>
           <td><?php echo $results[$key][7]?></td>
           <td><?php echo $results[$key][8]?></td>
           <td><?php echo $results[$key][9]?></td>
           <td><?php echo $results[$key][10]?></td>
           <td><?php echo $results[$key][11]?></td>
           <td><?php echo $results[$key][12]?></td>
           <td><?php echo $results[$key][13]?></td>
           <td><?php echo $results[$key][14]?></td>              
       </tr>
    <?php 
    }
}

duration1: 31.15542483 Secondes

for ($k=0;$k<30;$k++) {
    foreach ($results as $key1=>$val1){
        echo
           '<tr>
               <td>'.$results[$key1][0].'</td>
               <td>'.$results[$key1][1].'</td>
               <td>'.$results[$key1][2].'</td>
               <td>'.$results[$key1][3].'</td>
               <td>'.$results[$key1][4].'</td>
               <td>'.$results[$key1][5].'</td>
               <td>'.$results[$key1][6].'</td>
               <td>'.$results[$key1][7].'</td>
               <td>'.$results[$key1][8].'</td>
               <td>'.$results[$key1][9].'</td>
               <td>'.$results[$key1][10].'</td>
               <td>'.$results[$key1][11].'</td>
               <td>'.$results[$key1][12].'</td>
               <td>'.$results[$key1][13].'</td>
               <td>'.$results[$key1][14].'</td>              
           </tr>';
    }
}

duration2: 30.23169804 Secondes

for ($l=0;$l<30;$l++) {
    foreach ($results as $key2=>$val2){     
           echo'<tr>';
               echo'<td>'.$results[$key2][0].'</td>';
               echo'<td>'.$results[$key2][1].'</td>';
               echo'<td>'.$results[$key2][2].'</td>';
               echo'<td>'.$results[$key2][3].'</td>';
               echo'<td>'.$results[$key2][4].'</td>';
               echo'<td>'.$results[$key2][5].'</td>';
               echo'<td>'.$results[$key2][6].'</td>';
               echo'<td>'.$results[$key2][7].'</td>';
               echo'<td>'.$results[$key2][8].'</td>';
               echo'<td>'.$results[$key2][9].'</td>';
               echo'<td>'.$results[$key2][10].'</td>';
               echo'<td>'.$results[$key2][11].'</td>';
               echo'<td>'.$results[$key2][12].'</td>';
               echo'<td>'.$results[$key2][13].'</td>';
               echo'<td>'.$results[$key2][14].'</td>';              
           echo'</tr>';
    }
}

duration3: 27.54640007 Secondes

Pas beaucoup de différence entre les 2 méthodes originales, mais on dirait que c'est un peu plus rapide avec moins de concaténation @poke

Comme je doute que j'aurai besoin de autant de données en une fois, je suppose que je continuerai à utiliser de nombreuses balises, l'indentation du code semble plus nette et la disposition de la `` source de vue '' plus précise

Amien
la source
1
Un troisième cas de test serait d'utiliser plusieurs instructions d'écho avec une seule balise php, car vous n'auriez pas besoin d'utiliser la concaténation de chaînes alors.
poke le
J'ai refait les tests avec 50000 lignes et ajouté la méthode multi-écho en 1 tag aussi
Amien
5
+1 La mesure est importante lorsque nous voulons optimiser. On se rend souvent compte que ce genre d'optimisation est inutile.
Luc M
18
À première vue, les deux premiers exemples produisent beaucoup plus d'espaces que le dernier exemple. Cela pourrait être la raison de la durée d'exécution plus élevée.
Mike C
echoAccepte également plusieurs expressions à afficher. Aucune variante avec cette fonctionnalité n'a été prise en compte dans les métriques.
hakre
13

Vous pouvez facilement ignorer la différence de performance entre ces deux. Avec les ressources informatiques modernes d'aujourd'hui, la différence n'a vraiment pas d'importance. Ce genre de trucs d'impression à l'écran ne sont vraiment pas à craindre. Il y a des tonnes d'autres choses que vous devriez envisager avant. En dehors de cela, il y a toujours un débat entre les meilleures performances et la maintenabilité de votre code. Vous ne pouvez pas toujours essayer d'obtenir les meilleures performances. Au lieu de cela, vous devez toujours tenir compte des problèmes de performance ainsi que du temps que vous devez consacrer à leur amélioration.

pars
la source
6

Un code facile à traduire en pseudo-code est meilleur. Ceci est démontré par les exemples ci-dessus. Qu'est-ce qui prend plus de temps à dire?

"Start php, do this 30 times:, then stop php.  Print this.  Start php, print this, stop php. Print this.  Start php, print this, stop php.Print this.  Start php, print this, stop php. Print this.  Start php, print this, stop php.Print this.  Start php, print this, stop php. Print this.  Start php, print this, stop php.Print this.  Start php, print this, stop php..."

"Start php, do this 30 times: print this, then add this to that, then add this to that, then add this to that, then add this to that, then add this to that, then add this to that..."

"Start php, do this 30 times: print this, print this, print this, print this, print this, print this, print this..."

Personnellement, je ferais:

"Start php, define this, do this 30 times: add this to that.  Print." 

Une explication technique sur le fonctionnement de l'interprète et pourquoi une voie est plus rapide qu'une autre n'est pas pertinente pour un débutant. Il est préférable de connaître les règles de base:

  1. Plus simple est mieux.
  2. S'il ne tient pas sur une seule page, c'est qu'il en fait trop (décomposez-le).
  3. Si vous ne pouvez pas écrire manuellement le pseudo-code sur une fiche, c'est trop complexe.

Utilisez plus de balises si le résultat global est plus simple. Période.

Jon Egerton
la source
5

Le vrai problème avec cela est l'utilisation de la mémoire. La concaténation de chaînes et l'écho de masse peuvent augmenter l'utilisation de la mémoire de manière exponentielle.

Si vous spammez la balise php, votre code devient illisible.

La meilleure solution consiste à utiliser un moteur de modèle et à éviter de mélanger complètement le code et la présentation.

Martien de Jong
la source