2010-10-04 7 views
14

¿Cuál es la gran O de acceso a una matriz de JavaScript cuando se utiliza como un hash?¿Cuál es la gran O de serie de JavaScript cuando se utiliza como un hash?

Por ejemplo,

var x= []; 
for(var i=0; i<100000; i++){ 
    x[i.toString()+'a'] = 123; // using string to illustrate x[alpha] 
} 
alert(x['9999a']); // linear search? 

uno puede esperar motores JS no va a usar una búsqueda lineal internamente O (n), pero es a ciencia cierta?

+4

Nada es "seguro" (a menos que, como ocurre con C++, la norma define las características de funcionamiento de los contenedores?) pero puedo garantizar que ningún navegador utiliza una búsqueda lineal . Existe una competencia masiva para que los navegadores superen a los demás en los puntos de referencia de JS en estos días; puede estar seguro de que indexar una matriz será tan rápido como pueda hacerlo el fabricante del navegador. – meagar

Respuesta

7

En primer lugar matrices son de hecho hash. Siempre . Es por eso que x[5] === x["5"]:

var x = []; 
x[5] = 10; 
alert(x[5] === x["5"]); // true 

Los objetos son los hashes y arrays son sólo objetos especiales. Si desea usar hashes generales vaya para Objetos. Las "matrices asociativas" en Javascript son objetos. Las matrices son para datos numéricos indexados. Las matrices tienen una length propiedades y métodos de matriz similar a como push, pop, sort, etc., que no tiene sentido para ser utilizado en los hashes.

En cuanto a la gran O para buscar en Objetos: es implementación dependiente.

Probablemente los 2 mejores cosas que puede hacer para:

  1. Comprobar el código fuente de algunas implementaciones de navegador

  2. Haga un poco de punto de referencia para grandes n y hacer que su conclusión


la parte correspondiente del language specification:

4.3.3 objeto

un objeto es una colección de propiedades y tiene un solo objeto prototipo.

8.6.2 Propiedades de los objetos interna y los métodos

objetos Array tienen una implementación del método interno [[DefineOwnProperty]] ligeramente diferente. objetos Array dan tratamiento especial a una determinada clase de nombres de propiedades.

+1

Las matrices no son hash. El valor en 'x [" 5 "]' se convierte en 'number' antes de la búsqueda. Es por eso que obtienes el mismo resultado para 'x [5]' también. Sin embargo, 'Array' tiene' Object' en su cadena de prototipos, por lo tanto, no es un tipo en JavaScript y 'typeof ===" object "'. Lanza similar a '~~" 5 "' y si es igual a 0, entonces la matriz queda intacta, como en el caso de, digamos, 'x [" a5 "]'. – Tower

+0

Yo, por mi parte, di mis referencias (la ** especificación del lenguaje ** para ese asunto), ¿qué puede mostrar como la base de sus teorías completamente subjetivas y ** falsas? Aquí es donde el problema solía comenzar. – galambalazs

+1

(http://es5.github.com/#x15.4) '1.)' Las matrices son hashes, * "15.4 ** Array Objects **: los objetos de matriz dan un tratamiento especial a una determinada clase de ** nombres de propiedad **. "*' 2.) 'Los nombres de propiedad (incluso los índices de matriz) se tratan como cadenas: *" Un nombre de propiedad P (en forma de ** Valor de cadena **) es un ** índice de matriz ** si y solo si ToString (ToUint32 (P)) es igual a P y ToUint32 (P) no es igual a 232-1. "*' 3.) 'No arroja nada como' ~ ~ 'porque es un operador de doble bit que He recogido de algún tipo de artículo de optimización de raspado de bytes, y no está cerca de la especificación. – galambalazs

14

Se supone sintácticamente que se realiza el acceso a propiedades de objeto y elementos de matriz en JavaScript en constant time: O (1). Las características de rendimiento no están garantizadas en la especificación ECMAScript, pero todos los motores modernos de JavaScript recuperan propiedades de objetos en tiempo constante.

Aquí está un ejemplo simple que muestra cómo crecen los tiempos de acceso cuando el contenedor está tiempos x1000 más grandes:

var largeObject = {}; 
var smallObject = {}; 

var x, i; 

for (i = 0; i < 1000000; i++) { 
    largeObject['a' + i] = i; 
} 

for (i = 0; i < 1000; i++) { 
    smallObject['b' + i] = i; 
} 

console.time('10k Accesses from largeObject'); 
for (i = 0; i < 10000; i++) x = largeObject['a' + (i % 1000000)]; 
console.timeEnd('10k Accesses from largeObject'); 

console.time('10k Accesses from smallObject'); 
for (i = 0; i < 10000; i++) x = largeObject['a' + (i % 1000)]; 
console.timeEnd('10k Accesses from smallObject'); 

Resultados en Firebug, Firefox 3.6.10 (Mac OS X 10.6.4 - 2,93 GHz Intel Core 2 Duo):

10k Accesses from largeObject: 22ms 
10k Accesses from smallObject: 19ms 

resultados en Chrome 6.0.472 Herramientas de desarrollo:

10k Accesses from largeObject: 15ms 
10k Accesses from smallObject: 15ms 

Internet Expl ORER 8.0.7600 con Firebug Lite en Windows 7

10k Accesses from largeObject: 250ms 
10k Accesses from smallObject: 219ms 
+2

¿Puede señalar el párrafo en las especificaciones de ECMAScript o JavaScript que dice que se garantiza que el acceso a elementos de matriz o propiedades de objeto sea O (1)? AFAIK, JScript tiene una implementación O (n) que cumple perfectamente con los estándares como simples listas vinculadas. –

+1

@ Jörg: No se menciona en la especificación, por lo que en la práctica depende de la implementación ... Por eso elegí decir que se supone "sintácticamente". Sin embargo, reformulé mi respuesta para ser más preciso. –

+4

No sé cómo el equipo de IE puede vivir con resultados tan embarazosos ... – ChaosPandion

Cuestiones relacionadas