Foros del Web » Programando para Internet » PHP »

Depuración de código

Estas en el tema de Depuración de código en el foro de PHP en Foros del Web. Hola a todos. Quería preguntar si es más rápido de cargar en el servidor el método IF o el SWITCH. En mi caso utilizo gran ...
  #1 (permalink)  
Antiguo 03/01/2003, 17:53
Avatar de El Menda  
Fecha de Ingreso: junio-2001
Ubicación: Jaén
Mensajes: 516
Antigüedad: 22 años, 9 meses
Puntos: 0
Depuración de código

Hola a todos. Quería preguntar si es más rápido de cargar en el servidor el método IF o el SWITCH.
En mi caso utilizo gran cantidad de datos con los que procesar con IF, aunque me he dado cuenta que la función SWITCH me sirve igual porque realiza la misma tarea o función.
A ver si me ayudais. Gracias.
__________________
"No hay mujer fea sino copa de menos"
  #2 (permalink)  
Antiguo 03/01/2003, 19:16
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 2 meses
Puntos: 129
A nivel de tiempo de proceso no se como estará la cosa .. deben ser iguales mas o menos. Tu mismo puedes hacer la prueba usando funciones de microtime() para obtener segudos.microsegundos actuales .. y así hacer una pequeña "resta" entre el tiempo de inicio del proceso y el final comparando ambas rutinas via IF o Switch.

Lo que si es cierto q un Switch es mas claro q leer q una serie de IF .. elseif .. ademas de tener comodamente el estado "no es ninguna de las anteriores opciones".

Un saludo,
  #3 (permalink)  
Antiguo 03/01/2003, 19:24
Avatar de SpiceMan  
Fecha de Ingreso: noviembre-2002
Mensajes: 160
Antigüedad: 21 años, 4 meses
Puntos: 0
en general la excusa que se da es que usando switch en determinados casos es más elegante (para los estilistas del código), pero la verdad pura y simple es que switch es más rápido.

un test al respecto (en javascript) disponible en:

http://home.earthlink.net/~kendrasg/...jsOptMain.html

repitiendo 2 bloques de codigo que hacen exactamente lo mismo, toma el tiempo que tarda en hacerlo 100.000 veces tanto el if como el switch.

En todos los navegadores que lo probe, el ganador fue switch:

Internet Explorer: IF: 651ms Switch: 421ms
Mozilla: IF: 681ms Switch: 80ms (si! ochenta!!)
Opera: IF: 3465ms Switch: 1382ms

Con lo que se ve a las claras que lo más optimo es usar Switch. Ademas de ver que el Mozilla parece tener el engine de JavaScript más rápido y el Opera parece tener un javascript MUY lento.

Después de ver esa página hice mis propios tests en php:
Código PHP:
<?php

function microtime_diff($a$b) {
    list(
$a_dec$a_sec) = explode(" "$a);
    list(
$b_dec$b_sec) = explode(" "$b);
    return 
$b_sec $a_sec $b_dec $a_dec;
}

function 
ejecutarIf() {
    
$x=20;
    
$y=0;
    for (
$i=0$i 100000000$i++) {
        if (
$x==1) {$y $x;}
        else if(
$x==2) {$y=$x;}
        else if(
$x==3) {$y=$x;}
        else if(
$x==4) {$y=$x;}
        else if(
$x==5) {$y=$x;}
        else if(
$x==6) {$y=$x;}
        else if(
$x==7) {$y=$x;}
        else if(
$x==8) {$y=$x;}
        else if(
$x==9) {$y=$x;}
        else if(
$x==10) {$y=$x;}
        else if(
$x==11) {$y=$x;}
        else if(
$x==12) {$y=$x;}
        else if(
$x==13) {$y=$x;}
        else if(
$x==14) {$y=$x;}
        else if(
$x==15) {$y=$x;}
        else if(
$x==16) {$y=$x;}
        else if(
$x==17) {$y=$x;}
        else if(
$x==18) {$y=$x;}
        else if(
$x==19) {$y=$x;}
        else if(
$x==20) {$y=$x;}
    }
}

function 
ejecutarSwitch() {
    
$x=20;
    
$y=0;
    
    for (
$i=0$i 100000000$i++) {
        switch (
$x) {
            case 
$y=$x;break;
            case 
$y=$x;break;
            case 
$y=$x;break;
            case 
$y=$x;break;
            case 
$y=$x;break;
            case 
$y=$x;break;
            case 
$y=$x;break;
            case 
$y=$x;break;
            case 
$y=$x;break;
            case 
10 $y=$x;break;
            case 
11 $y=$x;break;
            case 
12 $y=$x;break;
            case 
13 $y=$x;break;
            case 
14 $y=$x;break;
            case 
15 $y=$x;break;
            case 
16 $y=$x;break;
            case 
17 $y=$x;break;
            case 
18 $y=$x;break;
            case 
19 $y=$x;break;
            case 
20 $y=$x;
        }
    }
}
echo 
"<b>Tiempos</b>:<br><br>\n";

$empezoIF microtime();
ejecutarIF();
$lapsoIf microtime_diff($empezoIFmicrotime());
printf("IF: %0.3f segundos<br>\n"$lapsoIf);

$empezoSwitch microtime();
ejecutarSwitch();
$lapsoSwitch microtime_diff($empezoSwitchmicrotime());
printf("SWITCH: %0.3f segundos<br>\n"$lapsoSwitch);
?>

Última edición por SpiceMan; 03/01/2003 a las 22:40
  #4 (permalink)  
Antiguo 03/01/2003, 20:37
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 2 meses
Puntos: 129
Pues muy bien SpiceMan .. ahora ya sabemos q swith es mas rápido ..

Lamentablemente no todo el mundo tiene el tiempo para estar testeando funciones .. seguro q si empezamos a testear por ejemplo .. usar un foreach() en vez de un for() para leer un array .. abrá sorpresas y así hasta con el simple echo() y print().

Un saludo,
  #5 (permalink)  
Antiguo 03/01/2003, 21:53
Avatar de Chaudx  
Fecha de Ingreso: marzo-2002
Ubicación: Quilpué, Chilito lindo
Mensajes: 345
Antigüedad: 22 años
Puntos: 2
De acuerdo ¡¡¡¡que wena!!!!!

Un gran reconocimiento para Spiceman, de verdad, eso es dedicación profesional al trabajo...
La verdad, es que nuuuuunca, se me ocurrió hacer la comparación entre switch o if....

Gracias por tu aporte y felicitaciones
__________________
Servicios computacionales
Linux registered User # 306587
Ubuntu user #14563
  #6 (permalink)  
Antiguo 03/01/2003, 22:39
Avatar de SpiceMan  
Fecha de Ingreso: noviembre-2002
Mensajes: 160
Antigüedad: 21 años, 4 meses
Puntos: 0
Error!

hace poco que empece a jugar con php, programo en otros lenguajes hace rato... y no sabia que llamar a una funcion sin los () no lo ejecutaba...

lo mas raro es que no dice nada... simplemente no ejecuta el código de la función.¿Alguien tiene alguna explicación de esto? No digo que sea así, pero es la sensación que me da.

Hay que modificar el codigo que puse poniendo parantesis en las funciones
ejecutarIf; => ejecutarIf();
ejecutarSwitch; => ejecutarSwitch();


de todas formas sigue ganando el switch

IF: 2.731 segundos
SWITCH: 1.117 segundos

Última edición por SpiceMan; 03/01/2003 a las 22:42
  #7 (permalink)  
Antiguo 03/01/2003, 22:47
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 2 meses
Puntos: 129
jajaj pues Urra por el switch ... (gana por poco xD) igual ya lo usaba por motivos "esteticos xD". y por el Default mas comodo q andar con elseif ...

Ahora a testear echo() y print() q a veces la gente lo pregunta xD .. Y si te pones con ello .. Bueno ya es sabido pero prueba en tus test con echo "hola mundo"; y echo 'hola mundo'; (lo digo por las comillas simples no evalua PHP .. y en las dobles si .. pese que no exista ninguna variable q usar ..

Lo de la llamada a la funcion .. NI idea .. nunca me habia dado por llamar a una funcion sin () .. Igual PHP lo intenta "interpretar" como una constante tipo define("funcionsinparentesis","") .. pero no creo .. ahi te hubiera dicho "constante no definida" o algo así digo yo? ..

Un saludo,
  #8 (permalink)  
Antiguo 03/01/2003, 23:00
Avatar de SpiceMan  
Fecha de Ingreso: noviembre-2002
Mensajes: 160
Antigüedad: 21 años, 4 meses
Puntos: 0
for vs foreach:


for: 3.218 segundos
foreach: 4.334 segundos
(array comun)



for: 3.339 segundos
foreach: 11.486 segundos
(array asociativo, claro que sin necesidad de saber la clave del array asociativo, sino el for no sirve para un array asociativo)


Echo vs Print:
Resultados muy irregulares, ejemplos:

echo: 0.734 segundos
print: 0.543 segundos

echo: 0.786 segundos
print: 0.616 segundos

echo: 0.783 segundos
print: 0.926 segundos

echo: 0.833 segundos
print: 0.980 segundos

echo: 0.824 segundos
print: 0.634 segundos

Pero en general (en un 70% de los casos) parece ser que print es más rapido (debe ser básicamente por aceptar un sólo argumento y no una lista como echo, pero devolver verdadero/falso seguramente le hace perder algo de terreno).
  #9 (permalink)  
Antiguo 03/01/2003, 23:04
Avatar de SpiceMan  
Fecha de Ingreso: noviembre-2002
Mensajes: 160
Antigüedad: 21 años, 4 meses
Puntos: 0
echo "a" vs echo 'a':

echo"": 0.739 segundos
echo'': 0.599 segundos

echo"": 0.824 segundos
echo'': 0.544 segundos

echo"": 0.770 segundos
echo'': 0.565 segundos

echo"": 0.728 segundos
echo'': 0.630 segundos


a si que todos a usar print 'Hola mundo!'
  #10 (permalink)  
Antiguo 03/01/2003, 23:12
Avatar de SpiceMan  
Fecha de Ingreso: noviembre-2002
Mensajes: 160
Antigüedad: 21 años, 4 meses
Puntos: 0
Ultimo test y me dejo de molestarlos:

Interpolacion vs Concatenación:

Interpolacion es hacer: print "Hola $nombre, como estas?";
Concatenación es hacer: print 'Hola '.$nombre.', como estas?';

Tiempos:

interpolacion: 0.864 segundos
concatenacion: 0.692 segundos

interpolacion: 0.965 segundos
concatenacion: 0.765 segundos

interpolacion: 0.897 segundos
concatenacion: 0.718 segundos

interpolacion: 0.895 segundos
concatenacion: 0.658 segundos



Espero que les sirva todo esto...

:-p :-p Y A OPTIMIZAR CÓDIGO !! :-p :-p

Última edición por SpiceMan; 03/01/2003 a las 23:15
  #11 (permalink)  
Antiguo 04/01/2003, 11:43
Avatar de chalito  
Fecha de Ingreso: diciembre-2002
Ubicación: Santiago, chile
Mensajes: 221
Antigüedad: 21 años, 2 meses
Puntos: 0
SpiceMan, pues mis mas sinceras felicitaciones
no es ninguna molestia lo que has echo, al contrario, creo que eso ayudo mucho, realmente nunca habia testeado ese tipo, de cosas, pero veo que la diferencia de tiempo realemente se enota, sonbre todo a la hora de tener muchos print o echo en una pagina, lo unico que me deciluciono fue que los foreach fuesen mas lentos, pues estoy muy acostumbrado a usar ese metodo, pero en fin, el cambio siempre bueno.

Saludos

Última edición por chalito; 04/01/2003 a las 13:00
  #12 (permalink)  
Antiguo 04/01/2003, 12:38
Avatar de SpiceMan  
Fecha de Ingreso: noviembre-2002
Mensajes: 160
Antigüedad: 21 años, 4 meses
Puntos: 0
si, yo vengo de trabajar mucho con perl y uso mucho el foreach por que en perl es más rápido foreach

Además el foreach en php no itera por referencia, itera por valor...
  #13 (permalink)  
Antiguo 04/01/2003, 21:21
O_O
 
Fecha de Ingreso: enero-2002
Ubicación: Santiago - Chile
Mensajes: 34.417
Antigüedad: 22 años, 2 meses
Puntos: 129
Spiceman .. para los test de for() y foreach() te faltó poner el código de los test.

Yo hice los mios (aprovechando y usando tus fuciones sobre microtime):

Código PHP:
<?php
function microtime_diff($a$b) {
    list(
$a_dec$a_sec) = explode(" "$a);
    list(
$b_dec$b_sec) = explode(" "$b);
    return 
$b_sec $a_sec $b_dec $a_dec;
}

$array=Array(1,2,3,4,5,6,7);

echo 
"<b>Tiempos</b>:<br><br>\n";

$empezo_foreach microtime();
foreach (
$array as $valor){
}

$lapso_foreach microtime_diff($empezo_foreachmicrotime());
printf("foreach: %0.8f segundos<br>\n"$lapso_foreach);

reset($array);

$empezo_for microtime();
for (
$i=0$i<= count($array); $i++){
}

$lapso_for microtime_diff($empezo_formicrotime());
printf("for: %0.8f segundos<br>\n"$lapso_for);


?>
Como se observa en el for .. uso count() para obtener el total de elementos del array .. Simulando lo que hace exactamente el forecha() a la hora de "parar" de leer el array cuando llega al final del último elemento.

No uso funciones para el codio a testear (he de ahí parte de los resultado y su resusltados .. pero la comparativa sirve igual).

Los resultados fueron (en tres iteracciones consecutivas):
foreach: 0.00025300 segundos
for: 0.00047600 segundos

foreach: 0.00024300 segundos
for: 0.00054600 segundos

foreach: 0.00025300 segundos
for: 0.00046200 segundos

Usando para el caso de test del for:
Código PHP:
$empezo_for microtime();
$total_array=count($array);
for (
$i=0$i<= $total_array$i++){

Los resultados fueron (en tres iteracciones consecutivas):
foreach: 0.00025300 segundos
for: 0.00031600 segundos

foreach: 0.00026400 segundos
for: 0.00034200 segundos

foreach: 0.00023600 segundos
for: 0.00039800 segundos

Al sacar fuera de cada iteraccion del bucle for el count() ganamos algo de tiempo .. acercandose al foreach() ..

Conclusión (bajo mis test y el código presentado):
Gana foreach() .. tambien se ve algo mas estable en cuanto a tiempos de respuesta en cada ejecución.

Test usando:
PHP 4.3.0RC1 en Windows98.

Un saludo,
  #14 (permalink)  
Antiguo 05/01/2003, 10:33
Avatar de SpiceMan  
Fecha de Ingreso: noviembre-2002
Mensajes: 160
Antigüedad: 21 años, 4 meses
Puntos: 0
yo tenía mal el código (calculaba el tiempo con una variable mal porque habia escrito $empezofor en vez de $empezoFor).

Código PHP:
<?php

for ($i 0$i 10000$i++) { $array[$i] = $i;}

function 
microtime_diff($a$b) {
    list(
$a_dec$a_sec) = explode(" "$a);
    list(
$b_dec$b_sec) = explode(" "$b);
    return 
$b_sec $a_sec $b_dec $a_dec;
}

function 
ejecutarFor() {
    global 
$array;
    
$copia $array;
    for (
$i=0$i 10$i++) { for ($i 0$i 10000$i++) { $copia[$i]++; } }
}

function 
ejecutarForeach() {
    global 
$array;
    
$copia $array;
    for (
$i=0$i 10$i++) { foreach ($copia as $key => $value) { $copia[$key]++; } }
}
$empezoFor microtime();
ejecutarFor();
$lapsoFor microtime_diff($empezoFormicrotime());


$empezoForeach microtime();
ejecutarForeach();
$lapsoForeach microtime_diff($empezoForeachmicrotime());
echo 
"<br><br><b>Tiempos</b>:<br><br>\n";
printf("for: %0.3f segundos<br>\n"$lapsoFor);
printf("foreach: %0.3f segundos<br>\n"$lapsoForeach);
?>
Con este código me da:


Tiempos:
for: 0.060 segundos
foreach: 0.984 segundos


reemplazando

foreach ($copia as $key => $value) { $copia[$key]++; }
por
foreach ($copia as $value) {$copia[$value]++; }


Tiempos:
for: 0.067 segundos
foreach: 0.977 segundos

parece no haber diferencia, habría que testearlo bien con un array asociativo con todas las de la ley.

Última edición por SpiceMan; 09/01/2003 a las 18:51
  #15 (permalink)  
Antiguo 06/01/2003, 15:04
Ex Colaborador
 
Fecha de Ingreso: junio-2002
Mensajes: 9.091
Antigüedad: 21 años, 9 meses
Puntos: 16
Hola,

Chicos, creo que os estais equivocando con el codigo que usais para comparar for y foreach. Yo incluso no veo la razon para hacer tal comparacion de velocidad. Una optimizacion basada en estos datos podria ser contraproducente. Es mas, os habeis olvidado del while.

En mi hulmilde opinion la optimizacion se debe hacer a nivel de algoritmo. Por ejemplo, el codigo de prueba de SpiceMan es una optimizacion de algoritmo. El for es mejor para el caso que quieres modificar el valor de todos los elementos del array, el uso del foreach es innecesario.

Ademas, el codigo de prueba debe hacer lo mismo para el for y para el foreach. En el codigo de Cluster, no hacen lo mismo. El codigo de for solo itera n veces, haciendo n llamadas a la funcion count(). El codigo del foreach recorre el array y en cada iteracion asigna a la variable $valor el valor correspondiente.

Por esto yo creo que lo mejor es hacer el codigo, hacer que funcione, hacer que funcione bien y por ultimo optimizarlo, tanto de velocidad como de calidad de codigo.

Por cierto, ¿que metodo seria el mas rapido para crear un array con incices de otro array, el for, el foreach o el while?

Saludos.
__________________
Josemi

Aprendiz de mucho, maestro de poco.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 03:51.