w3schools tag tab style page for color javascript memory sparse-array

javascript - tag - title of page html



¿Nula ocupa la memoria en javascript? (4)

Tengo la siguiente situación:

var large = [a,b,c,d,e,f,g,h,i]; var small = [a2, b2, c2, null, null, null, null, null, null, i2];

donde cada elemento de ambas matrices es un objeto.

La matriz pequeña contiene información relacionada con la más grande, pero no todos los elementos de large requieren un elemento asociado en small por lo que lo establecí en null . Sin embargo, todavía necesito mantener los índices iguales para poder hacer cosas como large[16].id + '': '' + small[16].description . ¿El hecho de que tenga una matriz cuyo valor es null en su mayoría resulta en un mayor uso de memoria?

Mi pregunta es si sería mejor o no hacer algo como small = [a2,b2,c2,i2] , y establecer índices en propiedades como a2.index = 0; b2.index = 1 a2.index = 0; b2.index = 1 y así sucesivamente.

También me he encontrado con una sugerencia de usar undefined en su lugar y alguien incluso mencionó la implementación de listas vinculadas. No creo que deba implementar una lista vinculada, ya que no estoy agregando o eliminando elementos con mucha frecuencia.


¿Por qué no poner los artículos pequeños en grandes [2] .small? De todos modos, normalmente no tiene que preocuparse por el consumo de memoria en javascript, pero aún así es mejor dejar las posiciones no utilizadas en pequeño indefinido (¡que es algo más que configurarlas como no definidas!), Para que el motor de javascript pueda decidir cambiar a una matriz dispersa (representada por una tabla hash en lugar de una matriz).


Las matrices son en realidad objetos con un tratamiento especial de propiedades con nombres que son índices de matriz.

Al asignar ''nulo'', creará cada propiedad, que utilizará una cantidad de memoria distinta de cero y, como ya se mencionó, ralentizará las búsquedas.

En su lugar, puede elidir los miembros no existentes, lo que dará como resultado una matriz dispersa:

var small = [a2, b2, c2,,,,,,, i2]; // small == [a2, b2, c2,undefined,undefined,undefined,undefined,undefined,undefined, i2]

Editar Tenga en cuenta que undefined ocupa espacio si lo asigna explícitamente a un elemento de matriz (o cualquier variable). Para recuperar memoria en este caso, deberá delete explícitamente el elemento. El estilo de inicialización que se muestra en mi ejemplo de código nunca asigna nada a los elementos elididos, por lo que no existen en absoluto. Esto se puede confirmar verificando la existencia de esos elementos como propiedades del objeto de matriz:

// continued from above small.hasOwnProperty(''3''); // returns false small[3] = undefined; small.hasOwnProperty(''3''); // now returns true because the property exists delete small[3]; small.hasOwnProperty(''3''); // returns false again alert(small.length); // alerts ''10'', showing that the array itself is still intact.


No puedo responder completamente a su pregunta, porque no estoy seguro de si null ocupa tanto espacio como explícitamente configurarlo como undefined . Pero creo que la forma estándar de hacer esto es usar el constructor Array :

var large = [1,2,3,4,5,6,7]; var small = new Array(large.length); small.length; // 7 small[0]; // undefined

Creo que esto usa menos memoria que la configuración explícita de valores no definidos, aunque el efecto es el mismo. He usado esto para una matriz dispersa con más de 250,000 índices, y no experimenté ningún problema de memoria (usando Google Chrome).

Edición: (después de jugar y hacer un poco más de investigación) A muchas personas no les gusta el new Array() constructor new Array() , por muchas razones (consulte, por ejemplo, esta discusión ). Pero creo que tiene un par de ventajas para arreglos grandes y dispersos:

  • Establece la propiedad de length correctamente. Si necesita que la longitud de la matriz coincida con su matriz grande, no puede hacer esto de otra manera sin configurarlo explícitamente ( small.length = large.length ) o poner algo no definido al final ( small[large.length-1] = undefined ).

  • No establece claves para índices vacíos, lo que me lleva a creer que usa menos memoria. Si tiene una matriz a = [null,null,null] o a = [undefined,undefined,undefined] , cada una de estas matrices tiene tres índices, y si usa a.map o a.forEach su función para cada una índice. Si usa a = new Array(3) y luego llama a.forEach , solo se llamará a su función para los índices que haya establecido explícitamente en un valor posterior a la construcción.

Pero no parece haber una gran diferencia de rendimiento entre:

var a = new Array(2000); a[2000] = 1;

y:

var = []; a[2000] = 1;

que también le da una matriz de longitud 2000 con un solo índice definido. Entonces, si no te importa si la length de small coincide con la de large , solo usaría var a = [] y la redimensionaríamos dinámicamente según sea necesario, desde la simple perspectiva de establecer y obtener valores en índices específicos, es exactamente lo mismo.


Nulo consumirá la memoria solo para el tamaño de una palabra ''NULL'' (en términos de intérprete), pero la búsqueda se ralentizará debido a la matriz abrumada con objetos que no irán al resultado de la búsqueda, y JS no tiene un Manera de optimizar esto. Debería utilizar mejor la matriz de objetos, y cada objeto debe mantener un valor y el índice.

El uso de indefinido es complicado también. En cuanto a la interpretación y el tamaño del script, esto aumentará la memoria, pero esto no es una parte de las especificaciones para avisar si undefined debería consumir memoria y cuánto, por lo que depende de un navegador, sus instalaciones para recolectar basura, consumir el montón de memoria. La mejor manera de ir es intentarlo, probablemente. Ejecute una matriz relativamente grande de NULL y undefined dentro de Chrome, tome una instantánea del montón y compare.