Javascript interruptor vs if...else if...else


Chicos tengo un par de preguntas:

  1. ¿Hay una diferencia de rendimiento en JavaScript entre una instrucción switch y una if...else?
  2. Si es así, ¿por qué?
  3. Es el comportamiento de switch y if...else diferente a través de los navegadores? (FireFox, IE, Chrome, Opera, Safari)

La razón para hacer esta pregunta es que parece que obtengo un mejor rendimiento en una declaración switch con aproximadamente 1000s casos en Firefox.


Editado No hay nada que hacer este no es mi código el Javascript está siendo producido lado del servidor de una biblioteca compilada y no tengo acceso al código. El método que está produciendo el javascript se llama

CreateConditionals(string name, string arrayofvalues, string arrayofActions)

Note arrayofvalues es una lista separada por comas.

Lo que produce es

function [name] (value) {
  if (value == [value from array index x]) {
     [action from array index x]
  }
}

Nota: donde [name] = el nombre pasado a la función serverside

Ahora cambié la salida de la función para insertarla en un área de texto, escribí un código JavaScript para analizar a través de la función, y lo convirtió en un conjunto de declaraciones case.

Finalmente corro la función y funciona bien, pero el rendimiento difiere en IE y Firefox.

Author: danwellman, 2010-05-27

9 answers

Respondiendo en generalidades:

  1. Sí, normalmente.
  2. Ver Más Información Aquí
  3. Sí, debido a que cada uno tiene un motor de procesamiento JS diferente, sin embargo, al ejecutar una prueba en el sitio a continuación, el switch siempre realiza el if, elseif en un gran número de iteraciones.

Lugar de ensayo

 83
Author: Tommy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-31 16:10:38

A veces es mejor usar ninguno de los dos. Por ejemplo, en una situación de "despacho", Javascript le permite hacer las cosas de una manera completamente diferente:

function dispatch(funCode) {
  var map = {
    'explode': function() {
      prepExplosive();
      if (flammable()) issueWarning();
      doExplode();
    },

    'hibernate': function() {
      if (status() == 'sleeping') return;
      // ... I can't keep making this stuff up
    },
    // ...
  };

  var thisFun = map[funCode];
  if (thisFun) thisFun();
}

Configurar la bifurcación de múltiples vías mediante la creación de un objeto tiene muchas ventajas. Puede agregar y eliminar funciones de forma dinámica. Puede crear la tabla de despacho a partir de datos. Puede examinarlo programáticamente. Puede construir los controladores con otras funciones.

Hay la sobrecarga añadida de una llamada a la función para llegar a la equivalente a un "caso", pero la ventaja (cuando hay muchos casos) de una búsqueda de hash para encontrar la función para una clave en particular.

 50
Author: Pointy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-27 16:53:37

La diferencia de rendimiento entre switch y if...else if...else es pequeña, básicamente hacen el mismo trabajo. Una diferencia entre ellos que puede hacer una diferencia es que la expresión a probar solo se evalúa una vez en un switch mientras que se evalúa para cada if. Si es costoso evaluar la expresión, hacerlo una vez es, por supuesto, más rápido que hacerlo cien veces.

La diferencia en la implementación de esos comandos (y todos los scripts en general) difiere bastante entre navegador. Es común ver diferencias de rendimiento bastante grandes para el mismo código en diferentes navegadores.

Como difícilmente puede probar el rendimiento de todo el código en todos los navegadores, debe elegir el código que mejor se adapte a lo que está haciendo, e intentar reducir la cantidad de trabajo realizado en lugar de optimizar cómo se hace.

 15
Author: Guffa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-27 16:53:06
  1. Si hay una diferencia, nunca será lo suficientemente grande como para ser notado.
  2. N / A
  3. No, todos funcionan de manera idéntica.

Básicamente, usa lo que haga que el código sea más legible. Definitivamente hay lugares donde una u otra construcción hace que sea más limpia, más legible y más fácil de mantener. Esto es mucho más importante que tal vez guardar unos pocos nanosegundos en código JavaScript.

 6
Author: Jon Benedicto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-27 16:36:43

Aparte de la sintaxis, un switch se puede implementar usando un árbol que lo hace O(log n), mientras que un if/else tiene que implementarse con un enfoque de procedimiento O(n). Más a menudo ambos se procesan procesalmente y la única diferencia es la sintaxis, y además, ¿realmente importa really a menos que estés escribiendo estáticamente 10k casos de if/else de todos modos?

 6
Author: Evan Carroll,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-27 16:42:55

Hay una diferencia en la actuación Javascript entre una sentencia switch y un si...si no....¿else?

No lo creo, switch es útil/corto si desea evitar múltiples condiciones if-else.

Es el comportamiento de switch y si...si no...otro diferente a través los navegadores? (FireFox, IE, Chrome, Opera, Safari)

El comportamiento es el mismo en todos los navegadores:)

 3
Author: Sarfraz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-27 16:35:52
  1. Workbenching podría dar lugar a algunas diferencias muy pequeñas en algunos casos, pero la forma de procesamiento depende del navegador de todos modos, por lo que no vale la pena molestar
  2. Debido a diferentes formas de procesamiento
  3. No se puede llamar un navegador si el comportamiento sería diferente de todos modos
 1
Author: Koen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-05-27 16:37:34

Resulta que if-else if generalmente más rápido que switch

Http://jsperf.com/switch-if-else/46

 1
Author: sidonaldson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-05 09:19:54

La respuesta de Pointy sugiere el uso de un objeto literal como una alternativa a switch o if/else. También me gusta este enfoque, pero el código en la respuesta crea un nuevo objeto map cada vez que se llama a la función dispatch:

function dispatch(funCode) {
  var map = {
    'explode': function() {
      prepExplosive();
      if (flammable()) issueWarning();
      doExplode();
    },

    'hibernate': function() {
      if (status() == 'sleeping') return;
      // ... I can't keep making this stuff up
    },
    // ...
  };

  var thisFun = map[funCode];
  if (thisFun) thisFun();
}

Si map contiene un gran número de entradas, esto puede crear una sobrecarga significativa. Es mejor configurar el mapa de acción solo una vez y luego usar el mapa ya creado cada vez, por ejemplo:

var actions = {
    'explode': function() {
        prepExplosive();
        if( flammable() ) issueWarning();
        doExplode();
    },

    'hibernate': function() {
        if( status() == 'sleeping' ) return;
        // ... I can't keep making this stuff up
    },
    // ...
};

function dispatch( name ) {
    var action = actions[name];
    if( action ) action();
}
 0
Author: Michael Geary,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-26 20:29:20