¿Abrir / cerrar etiquetas y rendimiento?

91

Esta puede ser una pregunta tonta, pero como alguien relativamente nuevo en PHP, me pregunto si hay problemas relacionados con el rendimiento para abrir y cerrar etiquetas PHP con frecuencia en el código de plantilla HTML y, de ser así, cuáles podrían ser las mejores prácticas en términos de trabajar con etiquetas PHP?

Mi pregunta no es sobre la importancia / corrección de las etiquetas de cierre, o sobre qué tipo de código es más legible que otro, sino sobre cómo se analiza / ejecuta el documento y qué impacto podría tener en el rendimiento.

Para ilustrar, considere los siguientes dos extremos:

Mezcla de etiquetas PHP y HTML:

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

Separación de etiquetas PHP y 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

Estaría interesado en escuchar algunas opiniones sobre esto, incluso si es solo para escuchar que no hace ninguna diferencia.

Gracias.

Tom
fuente
9
Interesante pregunta, +1 por eso. Aunque no creo que los 2 ejemplos que dio son el par ideal para comparar, entiendo la esencia :)
okw
Gracias ... Resulta que estoy trabajando con una tabla html masiva en este momento y la pregunta me está mirando fijamente ... incluso si es algo teórico.
Tom
Fuera de tema: debe usar un bucle y una matriz / iterador de datos para completar la tabla.
Decent Dabbler
@fireeyedboy ... claro, estoy de acuerdo, pero eso no siempre es práctico. O requiere acrobacias al obtener los datos de la base de datos, o la estructura HTML no encaja perfectamente en un bucle.
Tom
4
Creo que la legibilidad es lo más importante aquí. No verá ningún aumento o disminución importante con algo tan trivial como esto.
Chuck Le Butt

Respuestas:

88

3 reglas simples para que lo hagas bien:

  • Ningún problema de sintaxis puede afectar el rendimiento. La manipulación de datos sí lo hace.
  • Habla de rendimiento solo respaldado por los resultados de la elaboración de perfiles .
  • La optimización temprana es la raíz de todo mal

Los problemas de rendimiento son bastante difíciles de entender. Se aconseja a los novatos que no lo tengan en cuenta. Porque siempre les impresionan las cosas insignificantes y no ven las cosas realmente importantes. Solo por falta de experiencia.

Lo mismo para tu pregunta. Imagina que alguna vez obtendrás alguna diferencia. Incluso uno grande, digamos, un método es 2 veces más rápido. ¡Oh, 2 veces! Lo elegí y optimicé bien mi aplicación, ¡ahora se ejecutará un 50% más rápido!

Equivocado . No al 50%. Nunca notarías ni siquiera medirías este aumento de velocidad. Porque optimizó una parte que ocupa solo el 0,0001% del tiempo de ejecución completo del script.

En cuanto a las tablas HTML grandes, el navegador tarda mucho en representarlas. Mucho más de lo que tardó en generar.

La creación de perfiles es una palabra clave en el mundo del rendimiento. Se puede descartar cualquier pregunta relacionada con el rendimiento sin ninguna duda si no hay la palabra "perfilado" en ella. Al mismo tiempo, la elaboración de perfiles no es una ciencia espacial. Solo mido el tiempo de ejecución de diferentes partes de su script. Se puede hacer con algún generador de perfiles, como xdebug, o incluso manualmente, usando microtime(1). Y solo después de detectar la parte más lenta, puede comenzar con las pruebas.

Aprenda a crear perfiles antes de hacer preguntas sobre rendimiento. Y aprenda a no hacer preguntas sobre el rendimiento si no hay razones reales para ello.

La optimización prematura es la raíz de todos los males : D.Knuth .

Tu sentido común
fuente
4
¿Por qué es tan malo si uso la palabra "punto de referencia" en lugar de "perfil"? ¿Hay alguna diferencia en el significado? Agradecería conocer las diferencias :)
NikiC
+1 por citar a Donald Knuth y +200 por una respuesta muy perspicaz.
Clement Herreman
@nikic, ¿Cuándo dijo Col que era malo usar la palabra "punto de referencia"? Parece que le estás metiendo palabras en la boca o que estás haciendo referencia a algo en el lugar equivocado.
Chuck Le Butt
10
¿Por qué tiene esta calificación tan alta? No responde a la pregunta de ninguna forma. -1 de mí.
bharal
2
@NikiC El uso habitual que he presenciado: la evaluación comparativa significa de alguna manera medir o clasificar el rendimiento general de un fragmento de código para compararlo con soluciones alternativas (como lo que Amien ha hecho en su respuesta a esta pregunta, a continuación), mientras que la creación de perfiles significa averigüe qué partes de su código son responsables de cualquier problema de rendimiento visible para el usuario que esté tratando de resolver. La diferencia es que la creación de perfiles se trata de determinar la causa de su problema de rendimiento, mientras que la evaluación comparativa se trata de probar soluciones.
Mark Amery
40

He rehecho las pruebas con 50.000 filas y también he añadido el método de eco múltiple en 1 etiqueta

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 
    }
}

duración1: 31.15542483 Segundos

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>';
    }
}

duración2: 30.23169804 Segundos

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>';
    }
}

duración3: 27.54640007 Segundos

No hay mucha diferencia entre los 2 métodos originales, pero parece que es un poco más rápido con menos concatenación @poke

Como dudo que necesite esta cantidad de datos de una vez, supongo que seguiré usando muchas etiquetas, la sangría del código se ve más ordenada y el diseño de 'ver fuente' más preciso

Amien
fuente
1
Un tercer caso de prueba sería usar múltiples declaraciones de eco con una etiqueta php, ya que entonces no necesitaría usar la concatenación de cadenas.
empuje el
Rehice las pruebas con 50.000 filas y también agregué el método de eco múltiple en 1 etiqueta
Amien
5
La medición +1 es importante cuando queremos optimizar. A menudo nos damos cuenta de que este tipo de optimización es inútil.
Luc M
18
Por lo que parece, los dos primeros ejemplos generan muchos más espacios en blanco que el último ejemplo. Esa podría ser la razón del mayor tiempo de ejecución.
Mike C
También echoacepta múltiples expresiones para su salida. No se ha considerado ninguna variante con esa característica en las métricas.
hakre
13

Puede ignorar fácilmente la diferencia de rendimiento entre esos dos. Con los recursos informáticos modernos de hoy, la diferencia realmente no importa. Este tipo de cosas de impresión a pantalla son realmente de las que no debe preocuparse. Hay muchas otras cosas que deberías considerar antes. Aparte de eso, siempre hay un debate entre el mejor rendimiento y la facilidad de mantenimiento de su código. No siempre puede intentar lograr el mejor rendimiento. En cambio, siempre debe considerar las preocupaciones sobre el desempeño junto con la cantidad de tiempo que necesita dedicar a mejorarlas.

pars
fuente
6

El código que es fácil de traducir a pseudocódigo es mejor. Esto se evidencia en los ejemplos anteriores. ¿Qué tarda más en decir?

"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..."

Personalmente haría:

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

Una explicación técnica sobre cómo funciona el intérprete y por qué una forma es más rápida que otra es irrelevante para un novato. Es mejor conocer las reglas generales:

  1. Cuanto más simple, mejor.
  2. Si no cabe en una sola página, significa que está haciendo demasiado (desglosarlo).
  3. Si no puede escribir a mano el pseudocódigo en una tarjeta de índice, es demasiado complejo.

Use más etiquetas si el resultado general es más simple. Período.

Jon Egerton
fuente
5

El verdadero problema con esto es el uso de la memoria. La concatenación de cadenas y el eco masivo pueden aumentar exponencialmente el uso de memoria.

Si envía spam a la etiqueta php, su código se vuelve ilegible.

La mejor solución es utilizar un motor de plantillas y evitar mezclar el código y la presentación por completo.

Martien de Jong
fuente