16

Hace unas semanas, he leído este hilo Is < faster than <=? sobre operadores de comparación en C. Se dijo que no hay diferencia en el rendimiento entre < y <= ya que se interpretan como comandos de máquina iguales/similares.JavaScript - === vs == operadores rendimiento

Al mismo tiempo, en las "mejores prácticas" de nuestra empresa, se decía que siempre deberíamos usar "===" para comparar cosas en lugar de "==". Entonces, comencé a preguntarme si esto siempre es apropiado ya que estoy acostumbrado a usar "==" y "typeof ... ==" y no quiero cambiar mi forma de escribir: -]

Tenga en cuenta que esto es en el contexto de JavaScript.

Por lo tanto, tengo un poco de investigación y aquí Which equals operator (== vs ===) should be used in JavaScript comparisons? Se dice que:

Esto es debido a que el operador de igualdad == qué tipo coerción ... lo que significa que el intérprete intenta implícita para convertir los valores y luego hace la comparación.

Por otro lado, el operador === identidad no hace tipo la coacción, y por lo tanto no convierte los valores de los valores al comparar

y empecé a preguntarme si esto significa que cuando uso el operador "===" obtendré un buen rendimiento ya que no se gastarán recursos en la conversión de los operandos. Y después de que todo el código se convierte en comandos de máquina, ¿significa esto que así como no hay diferencia en C cuando usa < y <=, esto es lo mismo en JavaScript y en otros idiomas?

+18

El camino al infierno está pavimentado con micro-optimizaciones. – asawyer

+4

"Y después de que toda la codificación se convierta en comandos de máquina" Pero no todas las instrucciones en diferentes idiomas se convierten necesariamente en el mismo código de máquina. – BoltClock

+2

Intente echar un vistazo a esta publicación: http://stackoverflow.com/questions/8044750/javascript-dformance-difference-between-double-equals-and-triple-equals – Chase

Respuesta

0

para js, el operador === devolverá true si se usa en tipos de cadena y las cadenas son exactamente los mismos caracteres. Para los objetos, compara las referencias de objetos, no los contenidos.

Desde el ECMA standard:

11.9.6 La igualdad estricta Comparación Algoritmo La comparación x === y, donde x e y son los valores, produce verdadero o falso. Tal comparación se realiza como sigue:

  1. Si el Tipo (x) es diferente del tipo (y), de regreso falsa.
  2. Si Tipo (x) no está definido, devuelve verdadero.
  3. Si Tipo (x) es nulo, devuelve verdadero.
  4. Si Tipo (x) es Número, entonces a. Si x es NaN, devuelve falso. b. Si y es NaN, devuelve falso. c. Si x es el mismo valor numérico que y, devuelve verdadero. d. Si x es +0 e y es -0, devuelve verdadero. e. Si x es -0 e y es +0, devuelve verdadero. f. Falso retorno.
  5. Si Tipo (x) es Cadena, entonces devuelve verdadero si xey son exactamente la misma secuencia de caracteres (la misma longitud y los mismos caracteres en posiciones correspondientes); de lo contrario, devuelve falso.
  6. Si Tipo (x) es booleano, devuelva verdadero si xey son ambos verdaderos o ambos son falsos;
+6

Esto contiene información incorrecta (y la pequeña edición es una idea demasiado tardía). No es necesario que 'str === str' solo sea verdadero para el mismo objeto. '" a "+" b "===" ab "' es verdadero, pero no es necesario que '" a "+" b "' esté internado en el mismo objeto que '" ab "'. Mientras que * both * '==' y '===' podrían "detenerse anticipadamente" si la * implementación * decide que ambos son del mismo valor-objeto (esto sería una optimización específica de la implementación que funcionaría en * algunos * casos) , los valores de cadena deben compararse carácter por carácter con '==='. –

+0

Entonces, después de todo, hay mucha lógica detrás de esta muestra: signos iguales: -] ... Gracias por la respuesta y el enlace del libro de ESMA. Esto me parece muy interesante. – gotqn

+2

El primer párrafo es casi completamente incorrecto. Puedo brindarte una explicación detallada, si estás interesado. (¿Has estado escribiendo con un idioma diferente en mente?) –

3

No importa qué rendimiento obtenga, === es claramente la mejor opción en este caso. Cualquier otra cosa como un mejor rendimiento es solo la guinda del pastel. Además, la diferencia de cualquier manera es mínima.

3

La diferencia de rendimiento es insignificante, lo que significa que no debe desperdiciar sus preciosos ciclos cerebrales al pensar en ello. Si de verdad quieres saber, debes probar.

Use === a menos que tenga una buena razón para no hacerlo (probablemente no lo haga).

4

Es un lenguaje de scripting. El rendimiento de estos operadores no debería importar tanto que debería preocuparse por eso, porque hay muchas otras cosas que consumen mucha más potencia, como el hecho de que se ejecuta en una máquina virtual, está débilmente tipado, funciona con un DOM HTML dentro de un navegador ...

Además, ambos operadores hacen cosas muy diferentes, por lo que uno podría no ser intercambiable con el otro en cualquier caso.

Dicho esto, creo (pero no lo he probado) que === es más rápido. La razón es que solo necesita comparar el tipo, y si eso coincide, comparar los datos sin procesar. El operador == intentará convertir un tipo a otro si no coinciden. Esta será una operación más costosa en la mayoría de los casos.

Y eso es una suerte, porque en la mayoría de los casos === es la mejor opción.:)

Pero de todos modos, puedes probarlo fácilmente (asegúrate de probar múltiples casos, ambos con el mismo tipo y un par de tipos diferentes), pero si no sabes cómo probarlo, me detendría. preocupándose por eso por completo. La diferencia, si hay alguna, no te va a matar.

+1

Aunque genérico, como la mayoría de estas respuestas wrt '==' vs '===' "rendimiento", sospecho que la velocidad real de '==' y '===' está influenciada por los valores provistos. Mientras que las reglas '==' "parecen más largas" o "requieren más operaciones", se debe considerar que '==' es una "super coincidencia" de '===', por lo que siempre es posible intentar '= == 'reglas y detener si hay una coincidencia antes de las reglas' == '. Por supuesto, esto dependerá en última instancia de muchos otros factores, entre ellos, la * implementación *. –

+1

@pst, eso es correcto, pero si la velocidad es tan importante que debe usar tales comprobaciones dobles, es posible que desee considerar un idioma diferente al de Javascript. Además, si eres estricto con tus tipos (una variable es, por ejemplo, un entero o no asignada, pero nunca una cadena), puedes usar el operador de comparación estrictamente. Incluso en los casos en los que necesitaría '==', alternativamente podría realizar un encasillado. Creo que eso hace que tu código sea más legible y "más seguro", lo cual es más importante para mí que la velocidad. – GolezTrol

8

En primer lugar, el rendimiento simplemente no es una preocupación. Para cualquier script real, cualquier ganancia de rendimiento de usar un operador sobre el otro será infinitamente pequeña en comparación con otros cuellos de botella en el código (típicamente la manipulación DOM sería el objetivo número uno).

En segundo lugar, en muchos casos, == y === realizan exactamente los mismos pasos. Cuando los tipos de los dos operandos son iguales (dos cadenas o dos números, por ejemplo), la especificación ECMAScript tiene precisamente los mismos pasos para los dos operadores. Por lo tanto, si observa una diferencia de rendimiento entre los dos operadores para operandos del mismo tipo en un navegador u otro entorno, no hay garantía o incluso probabilidad de que vea una diferencia similar en otro navegador.

En el caso de typeof, como se menciona en su pregunta, los dos operandos se garantiza que sea del mismo tipo (cadena) y los dos operadores va a hacer exactamente lo mismo, por lo que las únicas razones para favorecer a un operador sobre el otro es estilístico.

La comunidad JS en su conjunto se ha mostrado bastante intransigente con esto: el consenso parece ser "nunca use == y != a menos que necesite una coerción tipo", lo cual es demasiado dogmático para mi gusto.

+1

Muchas veces, me han dado una gran cantidad de datos del servidor. Imagine mil filas, y cada valor en esta fila se debe comparar con otra cosa. Si la información vuelve como una cadena, y la comparo con "==" porque es un "número" después de todo, eso significa 1000 operaciones encubiertas. Es por eso que creo que el rendimiento importa. – gotqn

+0

@Joro: No estoy seguro de entender su punto. Si sus operandos son de tipos diferentes, '===' y '==' tendrán un comportamiento diferente, por lo que no hay elección: debe usar el que hace el tipo de comparación que desea. –

+0

Entiendo tu punto. Quería decir que tienes que estar preparado para cualquier situación. Los registros de retorno pueden estar en formato de cadena, pero después de un tiempo y las funciones del servidor se actualizan, se devuelven como números. Por lo tanto, la mejor solución, según yo, será usar "==" porque el formato de datos de devolución no me dependerá. – gotqn

4

Siento una respuesta con evidencia fácilmente verificable sería lo mejor.

Estas operaciones son tan pequeñas que es difícil probarlas.

  • == 1.648 cierto
  • === 1.629 cierto
  • prueba de control de 1.575 cierto

Si se resta de la prueba de control, parece que hay una diferencia ~ 30% en sus velocidades en mi navegador. Si haces esto varias veces, puedes obtener respuestas diferentes, pero === generalmente aparece más rápido, lo que creo es solo un testimonio de cuán insignificante es la diferencia.

Creo que esto prueba más o menos lo que otros decían, que la diferencia de rendimiento es una pérdida de tiempo para pensar, pero también muestra que === es realmente más rápido. Esperemos que esta respuesta pueda ahorrar tiempo a otras personas, aquellos que simplemente deben ver la prueba.

var testString = "42"; 
 
var testNumber = 42; 
 
var testObject = {}; 
 

 

 
var start = Date.now(); 
 
var result = null; 
 
for(var i = 0; i < 100000000; i++){ 
 
    result = testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject && 
 
    testString == testString && testNumber == testNumber && testObject == testObject 
 
} 
 

 
console.log("==", Date.now() - start, result); 
 

 
var start = Date.now(); 
 
var result = null; 
 
for(var i = 0; i < 100000000; i++){ 
 
    result = testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject && 
 
    testString === testString && testNumber === testNumber && testObject === testObject 
 
} 
 
console.log("===", Date.now() - start, result); 
 
var start = Date.now(); 
 
for(var i = 0; i < 100000000; i++){ 
 
    result = true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true && 
 
    true && true && true 
 
} 
 
console.log("control test", Date.now() - start, result);