values matriz for array javascript arrays performance v8 spidermonkey

for - matriz javascript



¿Las matrices de JavaScript se implementan realmente como matrices? (2)

La diferencia entre una Array javascript y un Object no es muy grande. De hecho, parece que Array agrega principalmente el campo de length , por lo que puede usar Array sy Object s como arrays numéricos:

var ar = new Array(); ar[0] = "foo"; ar["bar"] = "foo"; var ob = new Object(); ob[0] = "foo"; ob["bar"] = "foo"; assert(ar[0] == ob[0] == ar["0"] == ob["0"] == ar.bar == ob.bar); // Should be true.

Entonces, mi pregunta es, en los motores populares de javascript (V8, JavaScriptCore, SpiderMonkey, etc.), ¿cómo se maneja esto? Obviamente, ¡no queremos que nuestros arreglos se almacenen realmente como mapas hash con valores clave! ¿Cómo podemos estar razonablemente seguros de que nuestros datos se almacenan como una matriz real?

Por lo que puedo ver, hay algunos enfoques que los motores podrían tomar:

  1. Array se implementa exactamente de la misma forma que el Object , como una matriz asociativa con claves de cadena.
  2. Array es un caso especial, con una matriz tipo std::vector respalda las teclas numéricas y cierta heurística de densidad para evitar el uso de memoria demente si lo hace ar[100000000] = 0;
  3. Array es lo mismo que el Object , y todos los objetos obtienen una heurística para ver si usar una matriz tendría más sentido.
  4. Algo increíblemente complicado que no he pensado.

Realmente, esto sería más simple si hubiera un tipo de matriz adecuado (toses matrices de tipo WebGL, tos ).


En SpiderMonkey, las matrices se implementan básicamente como matrices C de jsvals. Estos se conocen como "matrices densas". Sin embargo, si comienzas a hacer cosas que no son de una matriz, como tratarlos como objetos, su implementación cambia a algo que se parece mucho a los objetos.

Moraleja de la historia: cuando quieras una matriz, usa una matriz. Cuando quieras un objeto, usa un objeto.

Oh, un jsval es una especie de tipo variadic que puede representar cualquier valor de JavaScript posible en un tipo C de 64 bits.


En V8 y Carakan (y probablemente Chakra), todos los objetos (no host) (tanto los que son arreglos como los que no lo son) con propiedades cuyos nombres son índices de arreglos (definidos en ES5) se almacenan como arreglos densos (una matriz C que contiene algún envoltorio de valor) o una matriz dispersa (que se implementa como un árbol de búsqueda binario).

La representación de objetos unificada se muestra en el sentido de que afecta el orden de enumeración: con un objeto, SpiderMonkey y SquirrelFish dan todas las propiedades en orden de inserción; y con una matriz, en general (¡hay casos especiales en SM al menos!) los índices de matriz primero y luego todas las demás propiedades en orden de inserción. V8, Carakan y Chakra siempre dan índices de matriz primero y luego todas las demás propiedades en orden de inserción, independientemente del tipo de objeto.