Ejecuté este código y obtuve el siguiente resultado. Tengo curiosidad por saber por qué []
es más rápido?
console.time('using[]')
for(var i=0; i<200000; i++){var arr = []};
console.timeEnd('using[]')
console.time('using new')
for(var i=0; i<200000; i++){var arr = new Array};
console.timeEnd('using new')
- usando
[]
: 299ms - utilizando
new
: 363 ms
Gracias a Raynos aquí hay un punto de referencia de este código y alguna forma más posible de definir una variable.
javascript
performance
Mohsen
fuente
fuente
[]
se equivelent quenew Array()
en términos de código fuente, no objetos devueltos expresiones de representaciónRespuestas:
Ampliando aún más las respuestas anteriores ...
Desde una perspectiva general de compiladores y sin tener en cuenta las optimizaciones específicas de VM:
Primero, pasamos por la fase de análisis léxico donde tokenizamos el código.
A modo de ejemplo, se pueden producir los siguientes tokens:
Esperemos que esto le proporcione una visualización suficiente para que pueda comprender cuánto se requiere más (o menos) procesamiento.
Según los tokens anteriores, sabemos que ARRAY_INIT siempre producirá una matriz. Por lo tanto, simplemente creamos una matriz y la completamos. En cuanto a la ambigüedad, la etapa de análisis léxico ya ha distinguido ARRAY_INIT de un descriptor de acceso de propiedad de objeto (por ejemplo
obj[foo]
) o corchetes dentro de cadenas / literales de expresiones regulares (por ejemplo, "foo [] bar" o / [] /)Esto es minúsculo, pero también tenemos más tokens con
new Array
. Además, todavía no está del todo claro que simplemente queremos crear una matriz. Vemos el token "nuevo", pero ¿"nuevo" qué? Luego vemos el token IDENTIFICADOR que significa que queremos un nuevo "Array", pero las máquinas virtuales de JavaScript generalmente no distinguen un token IDENTIFICADOR y tokens para "objetos globales nativos". Por lo tanto...Tenemos que buscar la cadena de alcance cada vez que nos encontramos con un token IDENTIFICADOR. Las máquinas virtuales de Javascript contienen un "objeto de activación" para cada contexto de ejecución que puede contener el objeto "argumentos", variables definidas localmente, etc. Si no podemos encontrarlo en el objeto de activación, comenzamos a buscar la cadena de alcance hasta llegar al alcance global . Si no se encuentra nada, lanzamos un
ReferenceError
.Una vez que hemos localizado la declaración de variable, invocamos al constructor.
new Array
es una llamada de función implícita, y la regla general es que las llamadas de función son más lentas durante la ejecución (de ahí que los compiladores estáticos de C / C ++ permitan la "función en línea", que los motores JS JIT como SpiderMonkey tienen que hacer sobre la marcha)El
Array
constructor está sobrecargado. El constructor de Array se implementa como código nativo, por lo que proporciona algunas mejoras de rendimiento, pero aún necesita verificar la longitud de los argumentos y actuar en consecuencia. Además, en el caso de que solo se proporcione un argumento, necesitamos verificar más a fondo el tipo del argumento. new Array ("foo") produce ["foo"] donde como new Array (1) produce [undefined]Para simplificarlo todo: con los literales de matriz, la VM sabe que queremos una matriz; con
new Array
, la VM necesita usar ciclos de CPU adicionales para descubrir qué hacenew Array
realmente .fuente
Una posible razón es que
new Array
requiere una búsqueda de nombreArray
(puede tener una variable con ese nombre en el alcance), mientras[]
que no.fuente
Array
exceptúa tanto un argumentolen
como múltiples argumentos. Donde como[]
solo acepta múltiples argumentos. Además, las pruebas de Firefox no muestran casi ninguna diferencia.var Array = window.Array
mejora el rendimiento de lanew Array
prueba.Buena pregunta. El primer ejemplo se llama una matriz literal. Es la forma preferida de crear matrices entre muchos desarrolladores. Podría ser que la diferencia de rendimiento se deba a la comprobación de los argumentos de la nueva llamada Array () y luego a la creación del objeto, mientras que el literal crea una matriz directamente.
Creo que la diferencia relativamente pequeña en el rendimiento respalda este punto. Por cierto, puede hacer la misma prueba con el objeto y el objeto literal {}.
fuente
Esto tendría sentido
http://www.dyn-web.com/tutorials/obj_lit.php
fuente
Además, interesante, si la longitud de la matriz se conoce de antemano (los elementos se agregarán justo después de la creación), el uso de un constructor de matriz con una longitud especificada es mucho más rápido en Google Chrome 70+ reciente.
" nueva matriz ( % ARR_LENGTH% ) " - 100% (más rápido) !
" [] " - 160-170% (más lento)
La prueba se puede encontrar aquí: https://jsperf.com/small-arr-init-with-known-length-brackets-vs-new-array/2
Nota: este resultado probado en Google Chrome v.70 + ; en Firefox v.70 e IE ambas variantes son casi iguales.
fuente