Tengo un modelo con posiblemente miles de objetos. Me preguntaba cuál sería la forma más eficiente de almacenarlos y recuperar un solo objeto una vez que tenga su identificación. Las identificaciones son números largos.
Estas son las 2 opciones en las que estaba pensando. en la opción uno es una matriz simple con un índice incremental. en la opción 2 es una matriz asociativa y tal vez un objeto, si hace la diferencia. Mi pregunta es cuál es más eficiente, cuando en su mayoría necesito recuperar un solo objeto, pero también a veces recorrerlo y ordenarlo.
Opción uno con matriz no asociativa:
var a = [{id: 29938, name: 'name1'},
{id: 32994, name: 'name1'}];
function getObject(id) {
for (var i=0; i < a.length; i++) {
if (a[i].id == id)
return a[i];
}
}
Opción dos con matriz asociativa:
var a = []; // maybe {} makes a difference?
a[29938] = {id: 29938, name: 'name1'};
a[32994] = {id: 32994, name: 'name1'};
function getObject(id) {
return a[id];
}
Actualizar:
OK, entiendo que usar una matriz en la segunda opción está fuera de discusión. Entonces, la línea de declaración, la segunda opción realmente debería ser: var a = {};
y la única pregunta es: qué está funcionando mejor al recuperar un objeto con una identificación dada: una matriz o un objeto donde la identificación es la clave.
y también, ¿cambiará la respuesta si tendré que ordenar la lista muchas veces?
fuente
Respuestas:
La versión corta: las matrices son en su mayoría más rápidas que los objetos. Pero no hay una solución 100% correcta.
Actualización 2017 - Prueba y resultados
Publicación original - Explicación
Hay algunas ideas falsas en su pregunta.
No hay matrices asociativas en Javascript. Solo matrices y objetos.
Estas son matrices:
Esta también es una matriz:
Básicamente es una matriz con agujeros, porque cada matriz tiene una indexación continua. Es más lento que las matrices sin agujeros. Pero iterar manualmente a través de la matriz es aún más lento (principalmente).
Este es un objeto:
Aquí hay una prueba de rendimiento de tres posibilidades:
Lookup Array vs Holey Array vs Object Performance Test
Una excelente lectura sobre estos temas en Smashing Magazine: escribir JavaScript eficiente en memoria rápida
fuente
if (a1[i].id = id) result = a1[i];
Debería ser:if (a1[i].id === id) result = a1[i];
Prueba http://jsperf.com/array-vs-object-performance/37 corrige esoEn realidad, no es una pregunta de rendimiento, ya que las matrices y los objetos funcionan de manera muy diferente (o se supone que lo hacen, al menos). Las matrices tienen un índice continuo
0..n
, mientras que los objetos asignan claves arbitrarias a valores arbitrarios. Si se desea proporcionar claves específicas, la única opción es un objeto. Si no te importan las claves, es una matriz.Si intenta establecer claves arbitrarias (numéricas) en una matriz, realmente tiene una pérdida de rendimiento , ya que, en términos de comportamiento, la matriz completará todos los índices intermedios:
(Tenga en cuenta que la matriz en realidad no contiene 99
undefined
valores, pero se comportará de esta manera ya que [se supone que] está iterando la matriz en algún momento).Los literales para ambas opciones deben dejar muy claro cómo se pueden usar:
fuente
user_id
" vs "que tiene claves,user_id
por lo que se puede acceder al objeto del usuario usandouser_id
como clave"? ¿Cuál es mejor en términos de rendimiento? Cualquier sugerencia sobre esto es apreciada :)Con ES6, la forma más eficaz sería utilizar un mapa.
Puede usar las funciones de ES6 hoy usando una cuña ( https://github.com/es-shims/es6-shim ).
El rendimiento variará según el navegador y el escenario. Pero aquí hay un ejemplo donde
Map
es más eficiente: https://jsperf.com/es6-map-vs-object-properties/2REFERENCIA https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map
fuente
efficiency
.En NodeJS si conoce el
ID
, el bucle a través de la matriz es muy lento en comparación conobject[ID]
.Y los resultados:
Incluso si la ID de búsqueda es la primera en la matriz / objeto:
fuente
Traté de llevar esto a la siguiente dimensión, literalmente.
Dada una matriz bidimensional, en la que los ejes xey son siempre de la misma longitud, ¿es más rápido:
a) busque la celda creando una matriz bidimensional y buscando el primer índice, seguido del segundo índice, es decir:
o
b) cree un objeto con una representación de cadena de las coordenadas xey, y luego haga una sola búsqueda en ese obj, es decir:
Resultado:
Resulta que es mucho más rápido hacer dos búsquedas de índice numérico en las matrices, que una búsqueda de propiedad en el objeto.
Resultados aquí:
http://jsperf.com/arr-vs-obj-lookup-2
fuente
Depende del uso. Si el caso es buscar objetos es muy rápido.
Aquí hay un ejemplo de Plunker para probar el rendimiento de la búsqueda de matrices y objetos.
https://plnkr.co/edit/n2expPWVmsdR3zmXvX4C?p=preview
Verás eso; Mirando hacia arriba para 5.000 artículos en la colección de matriz de longitud 5.000 , tome el control de
3000
miliseconosSin embargo , la búsqueda de 5.000 elementos en el objeto tiene 5.000 propiedades, take only
2
o3
miliseconsTambién hacer que el árbol de objetos no haga una gran diferencia
fuente
Tuve un problema similar al que tengo que enfrentar cuando necesito almacenar velas en vivo de una fuente de eventos limitada a x elementos. Podría tenerlos almacenados en un objeto donde la marca de tiempo de cada vela actuaría como la clave y la vela misma actuaría como el valor. Otra posibilidad era que pudiera almacenarlo en una matriz donde cada elemento era la vela misma. Un problema con las velas en vivo es que siguen enviando actualizaciones en la misma marca de tiempo donde la última actualización contiene los datos más recientes, por lo tanto, actualiza un elemento existente o agrega uno nuevo. Así que aquí hay un buen punto de referencia que intenta combinar las 3 posibilidades. Las matrices en la solución a continuación son al menos 4 veces más rápidas en promedio. Siéntete libre de jugar
La conclusión 10 es el límite aquí
fuente
Si tiene una matriz ordenada, puede hacer una búsqueda binaria y eso es mucho más rápido que una búsqueda de objetos, puede ver mi respuesta aquí:
Cómo buscar más rápido en una matriz ordenada usando Javascript
fuente