Tamaño máximo de una matriz en Javascript

108

Contexto: Estoy creando un pequeño sitio que lee un feed de rss y actualiza / verifica el feed en segundo plano. Tengo una matriz para almacenar datos para mostrar y otra que almacena ID de registros que se han mostrado.

Pregunta: ¿Cuántos elementos puede contener una matriz en Javascript antes de que las cosas comiencen a ponerse lentas o lentas? No estoy ordenando la matriz, pero estoy usando la función inArray de jQuery para hacer una comparación.

El sitio web seguirá funcionando y actualizándose y es poco probable que el navegador se reinicie / actualice con tanta frecuencia.

Si debería pensar en borrar algunos registros de la matriz, ¿cuál es la mejor manera de eliminar algunos registros después de un límite, como 100 elementos?

añadido
fuente
3
Probablemente se encontrará con más problemas con la pérdida de memoria del navegador de las barras de herramientas que del código JS. :) Firefox 4 Te señalo con el dedo.
epascarello
1
¿Con qué frecuencia verifica la matriz (ex intervalo de 2 s)? ¿Qué constituye lento (ex> 500ms)? ¿Qué orden de magnitud es su matriz (por ejemplo, miles, millones, miles de millones)?
zzzzBov
2
hacer pruebas comparativas con jsperf.com
VirtualTroll
Revisaré y actualizaré la matriz cada minuto. Y sí, lento sería un golpe de rendimiento que comienza a afectar esa carga y verificación, y otras animaciones en la página, ¡difíciles de definir, lo siento!
addedlovely
@Amine gracias por el enlace, parece que ese sitio web será mi nuevo mejor amigo :)
addedlovely

Respuestas:

153

La longitud máxima hasta que "se vuelve lento" depende totalmente de su máquina de destino y su código real, por lo que deberá probar en esa (esas) plataforma (s) para ver qué es aceptable.

Sin embargo, la longitud máxima de una matriz de acuerdo con la especificación ECMA-262 5th Edition está limitada por un entero de 32 bits sin signo debido a la operación abstracta ToUint32 , por lo que la matriz más larga posible podría tener 2 32 -1 = 4,294,967,295 = 4,29 mil millones de elementos .

maerics
fuente
13
@ Barkermn01: la especificación ECMA-262 5th Edition usa la operación abstracta ToUint32 para verificar la longitud de una matriz en cualquier operación que modifique su longitud, por lo que creo que la arquitectura subyacente de la máquina (o navegador web) es irrelevante.
maerics
1
hrm agradable, acabo de leer que un impresionante navegador de 64 bits es inútil en llamas entonces,
Barkermn01
3
@ Barkermn01, los navegadores de 64 bits todavía tienen muchas otras mejoras. Recuerde que ser un intérprete de JavaScript no es lo único que hace un navegador.
Razor Storm
1
Wowzer no hubiera esperado que fuera tan alto. Está bien, ¡creo que estaré bien!
addedlovely
En realidad, una matriz puede tener como máximo 4294967295 (2 ^ 31-1) elementos. Consulte stackoverflow.com/a/12766547/396458
NullUserException
26

No es necesario recortar la matriz, simplemente diríjala como un búfer circular (índice% maxlen). Esto asegurará que nunca sobrepase el límite (implementar un búfer circular significa que una vez que llega al final, vuelve al principio; no es posible sobrepasar el final de la matriz).

Por ejemplo:

var container = new Array ();
var maxlen = 100;
var index = 0;

// 'store' 1538 items (only the last 'maxlen' items are kept)
for (var i=0; i<1538; i++) {
   container [index++ % maxlen] = "storing" + i;
}

// get element at index 11 (you want the 11th item in the array)
eleventh = container [(index + 11) % maxlen];

// get element at index 11 (you want the 11th item in the array)
thirtyfifth = container [(index + 35) % maxlen];

// print out all 100 elements that we have left in the array, note
// that it doesn't matter if we address past 100 - circular buffer
// so we'll simply get back to the beginning if we do that.
for (i=0; i<200; i++) {
   document.write (container[(index + i) % maxlen] + "<br>\n");
}
Lelanthran
fuente
4
Idea inteligente, pero al hacer esto, posiblemente sobrescribirá los datos, confundirá los índices y posiblemente dará como resultado un comportamiento extraño.
john ktejik
9
La idea es implementar un búfer de anillo, así que sí, estás "olvidando" intencionalmente datos antiguos (para eso se usa un búfer de anillo) y eso fue lo que pidió el interrogador.
Lelanthran
1
Estaba aburrido haciendo clic en SO y encontré esta respuesta. Me encanta la técnica con la sobrescritura de índices según sea necesario.
Kyle Hotchkiss
5

Puede probar algo como esto para probar y recortar la longitud:

http://jsfiddle.net/orolo/wJDXL/

var longArray = [1, 2, 3, 4, 5, 6, 7, 8];

if (longArray.length >= 6) {
  longArray.length = 3;
}

alert(longArray); //1, 2, 3

orolo
fuente
2
Terminé usando slice ya que necesitaba recortar desde el inicio de la matriz, gracias.
añadido encantador
3

Como dijo @maerics, su máquina de destino y su navegador determinarán el rendimiento.

Pero para algunos números del mundo real, en mi Chromebook empresarial 2017, ejecutando la operación:

console.time();
Array(x).fill(0).filter(x => x < 6).length
console.timeEnd();
  • x=5e4 toma 16 ms, lo suficientemente bueno para 60 fps
  • x=4e6 tarda 250 ms, lo cual se nota pero no es gran cosa
  • x=3e7 tarda 1300 ms, lo cual es bastante malo
  • x=4e7 toma 11000ms y asigna 2.5GB extra de memoria

Entonces, alrededor de 30 millones de elementos es un límite superior estricto, porque la máquina virtual javascript cae por un precipicio a 40 millones de elementos y probablemente bloqueará el proceso.

Carl Walsh
fuente
2

He construido un marco de rendimiento que manipula y grafica millones de conjuntos de datos, e incluso entonces, la latencia de cálculo de JavaScript era del orden de decenas de milisegundos. A menos que esté preocupado por superar el límite de tamaño de la matriz, no creo que tenga mucho de qué preocuparse.

Tormenta de navajas
fuente
0

Dependerá mucho del navegador. 100 elementos no suena como un gran número; supongo que podrías ir mucho más alto que eso. Miles no deberían ser un problema. Lo que puede ser un problema es el consumo total de memoria.

rjmunro
fuente
0

Sin vergüenza, he extraído algunos conjuntos de datos bastante grandes en la memoria, y aunque se volvió lento, tomó tal vez 15 Mo de datos hacia arriba con cálculos bastante intensos en el conjunto de datos. Dudo que tenga problemas con la memoria a menos que tenga cálculos intensos en los datos y muchas filas. La elaboración de perfiles y la evaluación comparativa con diferentes conjuntos de resultados simulados será su mejor opción para evaluar el rendimiento.

Stefgosselin
fuente