Noticias

¡RECUERDA QUE SI ERES UN NUEVO USUARIO, DEBES PRESENTARTE PARA PODER PUBLICAR MENSAJES! | TENEMOS CANAL OFICIAL DE TELEGRAM: t.me/unity3dspain

switch or else

Iniciado por Igor, Octubre 07, 2017, 02:13:59 PM

Tema anterior - Siguiente tema
holas
 
tengo dudas sobre "switch", sobre su eficacia en varios casos diferentes...
 
porejemplo si solo son tres casos(case) en el switch, es mas eficiente hacerlo con if .... else if.... else? o es mejor con switch?
 
osea:
 

switch (numero) {
   case 1:
      unaFuncion();
      break;
   case 2:
      otraFuncionDiferente();
      break;
   defalt:
      laUltimaFuncionDiferente();
      break;
}
//o es mejor esta otra forma?
if (numero = 1) {
   unaFuncion();
} else if (numero = 2) {
   otraFuncionDiferente();
} else {
   laUltimaFuncionDiferente();
}

 
 
 
y que pasa si envez de pocos casos son un monton.... pongamos 128 casos diferentes? eso hace que "switch" pierda eficacia???
 
y que opinan de "encadenar" en "cascada" un monton de "ifs"(if) ? porejemplo 5 ifs
 
osea:
 

if (numero = 1) {
   tal;
} else {
   if (numero = 2) {
      talOtraCosa;
   } else {
      if (numero = 3) {
         otraCosaMas;
      } else {
         if (numero = 3) {
         } else {
            if (numero = 4) {
               cosaMuyRara;
            } else {
               if (numero = 5) {
                  ultimaCosa;
               }
            }
         }
      }
   }
}

 
haiba, jaja, he repetido el "case 3" y me he liado al escribir, me va a dar errores por todos los lados al compilar.... parsing error, caso ya declarado.... pero creo que se entiende el ejemplo
 
en este caso seria mejor un switch? creo que si, pero es por pedir la opinion de algun "experto"

En cuando optimizacion no hay mucha diferencia cuando son pocas variables, ya cuando son muchas es mejor usar switch (por como lo trata el compilador, segun lei), por mi parte usa switch porque te genera un codigo mas limpio.

Octubre 07, 2017, 03:18:36 PM #2 Ultima modificación: Octubre 07, 2017, 03:32:53 PM por lightbug
Hola, podes encontrar la solucion si ves que hace un if-else vs un switch en C/C++ (funciona similar) en assembly. Aca una pagina de internet que a partir del compilador te elabora un codigo (para contrastar resultados y ver en general como se traduce todo va bien):
 
https://godbolt.org/
 
Segun tengo entendido siempre el switch gana para mas casos ya que la forma en que salta al resultado deseado la realiza de forma distinta a como se llega en un if else. Para un if else, si queres llegar al ultimo tenes que soportar todas las comparaciones y saltos hasta llegar. En un switch la cosa es distinta, se utiliza una lookUp table cuando tus etiquetas superan un cierto numero, basicamente accedes a cualquier caso con igual tiempo de procesamiento ya que todas las posibles posiciones de memoria estan indexadas en esta gran tabla. Igual los tiempos de un if-else vs un switch para pocos casos son muy similares y ademas el switch es mucho mas sexy, asi que si tenes que elegir no cambia mucho la verdad. Hay que tener en cuenta que el switch no se usa igual que un if else, en uno metes y realizas cualquier cosa, en un switch no podes evaluar floats, double, strings ,etc. En un if-else podes ir anidando codigo, que en un switch es "esto o aquello".
 
Edito: no lo tomes como la biblia a esto que dije, lo recuerdo esto del curso de programacion de la universidad jaja

 
 
Cita de: lightbug date=1507382316...el switch es mucho mas sexy
   


jejejeje
 
gracias por las respuestas

el switch es mejor, pero a mi personalmente nunca me a gustado jajaja, también decir que con el switch puedes jugar con el break; para que ejecute diferentes casos a la vez y eso le da mas juego, piensa que con el if en vez de "saltar" cada vez que llega a un caso se hace la pregunta de "sí pasa esto" y por lógica se entiende que consume más por el simple echo que en cada caso se pregunta si se cumple o no
Cita de: lightbug date=1507382316En un if-else podes ir anidando codigo, que en un switch es "esto o aquello".
   


bueno puedes meter un switch dentro de otro switch o un if-else dentro del switch o agrupar bien los casos de switch y jugar con el break
 
Cita de: Igor date=1507378439y que pasa si envez de pocos casos son un monton.... pongamos 128 casos diferentes? eso hace que "switch" pierda eficacia???
   


pues lo que pase seguramente es que hay alguna forma mejor de gestionar tantos casos en vez de usar condicionales XD, depende de lo que tengas que programar

Yo siempre que puedo utilizo switch, me parece más fácil de leer.
 
En el ejemplo que has puesto del if, ¿no sería mejor utilizar "else if" que hacer un else y después dentro de este else un if? Lo digo porque con tanto else e if se ve super embarullado.

gracias a todos
 
 
 
@TheBullet, el ejemplo del if era solo un ejemplo, y si que quedo lioso, jeje
 
@Kvashir, si, ya suelo hacerlo cuando es necesario, porejemplo:
 

switch (numero) {
   case 1:
      unaCosa;
      break;
   case 2:
   case 3:
   case 4:
      otraCosa;
      break;
   default:
      break;
}

 
 
 
@gZone no tengo ni idea que es eso de benchmarks.... pero lo miro ahora mismo...
 
 
 
y la pregunta era por comfirmar la eficacia de "switch" frente "if" en casos de pocos "casos"...
 
y para casos de muchos "casos" mejor hacer "caso" a Piog(el tiene el poder)
 
;)
 
ok, ya he visto que es benchmark, un test/prueba de rendimiento sometiendo a "estres" el programa o funcion.... 
 
algo asi como saturar la CPU...
 
para mi pregunta en concreto seria haciendo porejemplo un bucle de 200.000 repeticiones de la misma funcion y comparando el tiempo de ejecucion usando primero "ifs" y luego "switches"
 
(puedo marcarme a mi mismo como mejor respuesta a mi propia pregunta?)
 
jeje, gracias a todos

Cita de: gZone date=1507615938.. sobre rendimiento, depende mucho de la plataforma y no tanto/solo del compilador y su salida.
   


seguro? a mi me parece que switch es mas eficiente ya que su funcionamiento es el mismo programe como se programe...
 
en un if siempre se va a ejecutar la condición para comprobar si se cumple o no, en un switch no 

Cita de: gZone date=1507660562la comparativa también dependerá del nivel de anidación del if ... pero lo ideal es el "switch"
   


me dices que no y después me das la razón, pégate un tiro, nivel de anidación del if? siempre sera mejor el switch... anides como anides el if en el switch se busca el valor correcto y no se consulta cada condición. es como buscar una key en un diccionario 

Octubre 10, 2017, 11:49:00 PM #9 Ultima modificación: Octubre 10, 2017, 11:54:46 PM por Braltor
para muchos "casos" es mas rapida una lista o incluso un diccionario de funciones que if-else o switch, y se pueden optimizar dinamicamente

Cita de: Braltor date=1507672140para muchos "casos" es mas rapida una lista o incluso un diccionario de funciones que if-else o switch, y se pueden optimizar dinamicamente
   


esta claro, pero lee el título del post XD

test de rendimiento realizado (5 millones de repeticiones)
 
he probado casos de 3, 4 y 5 casos,
 
probado en el editor, en mi PC (tiene diez años, windows XP) (si alguien mas lo prueba estaria bien)
 
resultado:   pese a lo que la mayoria  pensaba, Gana "IF"
 
tiempos de "ejecucion" de las diferentes funciones:
 
 
 
if de 3 = 0.419 segundos
 
if de 4 = 0.435 segundos
 
if de 5 = 0.449 segundos
 
 
 
switch de 3 = 0.439 segundos
 
switch de 4 = 0.459 segundos
 
switch de 5 = 0.464 segundos
 
 
 
switch de 24 = 0.475 segundos
 
 
 
codigo de la prueba:
 


void switch3() {
   float timeUsed = Time.realtimeSinceStartup;
   string text = "";
   for (int i = 0; i < 5000000; i++) {
      int num = Random.Range(0,3);
      switch (num) {
         case 1:
            text = "hola";
            break;
         case 2:
            text = "hey!";
            break;
         default:
            text = "hellow";
            break;
      }
   }
   timeUsed = Time.realtimeSinceStartup - timeUsed;
   Debug.Log(timeUsed);//resultado tiempo medio usado = 0.439 segundos
}
void switch4() {
   float timeUsed = Time.realtimeSinceStartup;
   string text = "";
   for (int i = 0; i < 5000000; i++) {
      int num = Random.Range(0,4);
      switch (num) {
         case 1:
            text = "hola";
            break;
         case 2:
            text = "hey!";
            break;
         case 3:
            text = "xxxxxx";
            break;
         default:
            text = "hellow";
            break;
      }
   }
   timeUsed = Time.realtimeSinceStartup - timeUsed;
   Debug.Log(timeUsed);//resultado tiempo medio usado = 0.459 segundos
}

void switch5() {
   float timeUsed = Time.realtimeSinceStartup;
   string text = "";
   for (int i = 0; i < 5000000; i++) {
      int num = Random.Range(0,5);
      switch (num) {
         case 1:
            text = "hola";
            break;
         case 2:
            text = "hey!";
            break;
         case 3:
            text = "xxxxxx";
            break;
         case 4:
            text = "555555";
            break;
         default:
            text = "hellow";
            break;
      }
   }
   timeUsed = Time.realtimeSinceStartup - timeUsed;
   Debug.Log(timeUsed);//resultado tiempo medio usado = 0.464 segundos
}   






void if3() {
   float timeUsed = Time.realtimeSinceStartup;
   string text = "";
   for (int i = 0; i < 5000000; i++) {
      int num = Random.Range(0,3);
      if (num == 1) {
         text = "hola";
      } else if (num == 2) {
         text = "hey!";
      } else {
         text = "hellow";
      }
   }
   timeUsed = Time.realtimeSinceStartup - timeUsed;
   Debug.Log(timeUsed);//resultado tiempo medio usado = 0.419 segundos
}

void if4() {
   float timeUsed = Time.realtimeSinceStartup;
   string text = "";
   for (int i = 0; i < 5000000; i++) {
      int num = Random.Range(0,4);
      if (num == 1) {
         text = "hola";
      } else {
         if (num == 2) {
            text = "hey!";
         } else {
            if (num == 3) {
               text = "xxxxxx";   
            } else {
               text = "hellow";
            }
         }
      }
   }
   timeUsed = Time.realtimeSinceStartup - timeUsed;
   Debug.Log(timeUsed);//resultado tiempo medio usado = 0.435 segundos
}

void if5() {
   float timeUsed = Time.realtimeSinceStartup;
   string text = "";
   for (int i = 0; i < 5000000; i++) {
      int num = Random.Range(0,4);
      if (num == 1) {
         text = "hola";
      } else {
         if (num == 2) {
            text = "hey!";
         } else {
            if (num == 3) {
               text = "xxxxxx";   
            } else {
               if (num == 5) {
                  text = "555555";
               } else {
                  text = "hellow";
               }
            }
         }
      }
   }
   timeUsed = Time.realtimeSinceStartup - timeUsed;
   Debug.Log(timeUsed);//resultado tiempo medio usado = 0.449 segundos
}













void switch24() {
   float timeUsed = Time.realtimeSinceStartup;
   string text = "";
   for (int i = 0; i < 5000000; i++) {
      int num = Random.Range(0,24);
      switch (num) {
         case 1:
            text = "hola";
            break;
         case 2:
            text = "hey!";
            break;
         case 3:
            text = "xxxxxx";
            break;
         case 4:
            text = "hola";
            break;
         case 5:
            text = "hey!";
            break;
         case 6:
            text = "xxxxxx";
            break;
         case 7:
            text = "hola";
            break;
         case 8:
            text = "hey!";
            break;
         case 9:
            text = "xxxxxx";
            break;
         case 10:
            text = "hola";
            break;
         case 11:
            text = "hey!";
            break;
         case 12:
            text = "xxxxxx";
            break;
         case 13:
            text = "hola";
            break;
         case 14:
            text = "hey!";
            break;
         case 15:
            text = "xxxxxx";
            break;
         case 16:
            text = "hola";
            break;
         case 17:
            text = "hey!";
            break;
         case 18:
            text = "xxxxxx";
            break;
         case 19:
            text = "hola";
            break;
         case 20:
            text = "hey!";
            break;
         case 21:
            text = "xxxxxx";
            break;
         case 22:
            text = "hola";
            break;
         case 23:
            text = "hey!";
            break;
         case 24:
            text = "xxxxxx";
            break;
         default:
            text = "hellow";
            break;
      }
   }
   timeUsed = Time.realtimeSinceStartup - timeUsed;
   Debug.Log(timeUsed);//resultado tiempo medio usado = 0.475 segundos
}

 
 

Cita de: Igor date=1507710854resultado:   pese a lo que la mayoria  pensaba, Gana "IF"
   


Yo te dije eso mas arriba, if gana para pocos casos. Hace un if else de 10 vs un switch de 10 y elegí siempre el último caso, o el penúltimo.

Octubre 11, 2017, 04:07:53 PM #13 Ultima modificación: Octubre 11, 2017, 04:10:36 PM por Igor
test a peticion de @lightbug
 
mismo PC de 10 años, windows xp
 
5 millones de repeticiones
 
10 casos diferentes eligiendo siempre el ultimo caso/if
 
(hay que tener en cuenta que en el bucle ya no hay un Random.Range repitiedose 5 millones de veces, he puesto un valor fijo para "num")
 
if de 10 = 0.125 segundos
 
switch de 10 = 0.061 segundos
 
GANA SWITCH (eligiendo el ultimo caso, pasando por todos los "if"
 
(con esto queda claro que random.range es una funcion que gasta como unos 30 "if")  :)
 
jeje y es una pasada ver que comprueba 10ifs 5millones de veces...(y asigna: "num=10" y "text="algo"" cinco millones de veces) en una decima de segundo...
 
 
 
bueno, prueba con 5 casos (eligiendo el ultimo)
 
if de 5 = 0.080 segundos
 
switch de 5 = 0.064 segundos
 
 
 
sigue ganando switch (eligiendo siempre el ultimo caso)

Ya veo que os lo habéis currado, pero el sin duda alguna ..... el switch.
 
porque el if-else-if:
 


  •    lo odio.


  •    lo aborrezco


  •    lo tengo aversión.


  •    me toca las narices


  •    me cabrea seguirle la pista


  •    me putea


  •    y me pone de los nervios


Y todo a la vez.... encima es multitaréa  Como el Windows.
 
(no se si se ha notado que no me gusta nada )

Etiquetas: