Tamanho máximo de uma matriz em Javascript

108

Contexto: Estou construindo um pequeno site que lê um feed rss e atualiza / verifica o feed em segundo plano. Eu tenho uma matriz para armazenar dados a serem exibidos e outra que armazena IDs de registros que foram mostrados.

Pergunta: Quantos itens um array pode conter em Javascript antes que as coisas comecem a ficar lentas ou lentas. Não estou classificando a matriz, mas estou usando a função inArray do jQuery para fazer uma comparação.

O site continuará funcionando e atualizando, e é improvável que o navegador seja reiniciado / atualizado com tanta frequência.

Se eu fosse pensar em limpar alguns registros do array, qual é a melhor maneira de remover alguns registros após um limite, como 100 itens.

adicionado adorável
fonte
3
Você provavelmente terá mais problemas com o vazamento de memória do navegador nas barras de ferramentas do que no código JS. :) Firefox 4 Eu aponto meu dedo para você.
epascarello
1
Com que frequência você verifica a matriz (intervalo ex 2s)? O que constitui lentidão (ex> 500ms)? Qual é a ordem de magnitude do seu array (ex milhares, milhões, bilhões)?
zzzzBov
2
faça testes de benchmark com jsperf.com
VirtualTroll
Estarei verificando e atualizando o array a cada minuto. E sim lento seria um hit de desempenho que começa a efetuar esse carregamento e verificação, e outras animações na página, difícil de definir desculpe!
adorável
@Amine, obrigado pelo link, parece que aquele site será meu novo melhor amigo :)
adorável

Respostas:

153

O comprimento máximo até "ficar lento" depende totalmente da sua máquina-alvo e do seu código real, então você precisará testar nessa (s) plataforma (s) para ver o que é aceitável.

No entanto, o comprimento máximo de uma matriz de acordo com a especificação ECMA-262 5ª Edição é limitado por um inteiro de 32 bits sem sinal devido à operação abstrata ToUint32 , então a maior matriz possível poderia ter 2 32 -1 = 4,294,967,295 = 4,29 bilhões de elementos .

matemática
fonte
13
@ Barkermn01: a especificação ECMA-262 5ª Edição usa a operação abstrata ToUint32 para verificar o comprimento de uma matriz em qualquer operação que modifique seu comprimento, então acho que a arquitetura subjacente da máquina (ou navegador da web) é irrelevante.
maerics
1
hrm legal, acabei de ler que um incrível navegador de 64 bits está
ficando
3
@ Barkermn01, os navegadores de 64 bits ainda têm muitas outras melhorias. Lembre-se de que ser um intérprete de javascript não é a única coisa que um navegador faz.
Razor Storm
1
Wowzer não esperava que fosse tão alto. OK legal, acho que vou ficar bem!
adorável
Na verdade, uma matriz pode ter no máximo 4294967295 (2 ^ 31-1) elementos. Consulte stackoverflow.com/a/12766547/396458
NullUserException
26

Não há necessidade de aparar a matriz, simplesmente endereça-a como um buffer circular (índice% maxlen). Isso garantirá que ele nunca ultrapasse o limite (implementar um buffer circular significa que, uma vez que você chegue ao final, você retorne ao início novamente - não é possível ultrapassar o final do array).

Por exemplo:

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
fonte
4
Idéia inteligente, mas com isso você poderá sobrescrever dados, índices confusos e, possivelmente, resultando em um comportamento estranho.
john ktejik
9
A ideia é implementar um buffer em anel, então sim - você está intencionalmente "esquecendo" dados antigos (é para isso que um buffer em anel é usado) e foi isso que o questionador pediu.
Lelanthran
1
Eu estava entediado clicando em SO e encontrei esta resposta. amo a técnica com índices de substituição conforme necessário.
Kyle Hotchkiss
5

Você pode tentar algo assim para testar e cortar o comprimento:

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
fonte
2
Acabei usando uma fatia, pois precisava aparar desde o início da matriz, mas obrigado.
adorável
3

Como @maerics disse, sua máquina-alvo e navegador irão determinar o desempenho.

Mas para alguns números do mundo real, em meu Chromebook corporativo de 2017, executando a operação:

console.time();
Array(x).fill(0).filter(x => x < 6).length
console.timeEnd();
  • x=5e4 leva 16 ms, bom o suficiente para 60 fps
  • x=4e6 leva 250 ms, o que é perceptível, mas não é grande coisa
  • x=3e7 leva 1300ms, o que é muito ruim
  • x=4e7 leva 11000ms e aloca 2,5 GB extras de memória

Portanto, cerca de 30 milhões de elementos é um limite superior rígido, porque a VM javascript cai de um penhasco com 40 milhões de elementos e provavelmente travará o processo.

Carl Walsh
fonte
2

Eu construí uma estrutura de desempenho que manipula e representa graficamente milhões de conjuntos de dados e, mesmo assim, a latência de cálculo de javascript era da ordem de dezenas de milissegundos. A menos que você esteja preocupado em ultrapassar o limite de tamanho do array, não acho que tenha muito com que se preocupar.

Razor Storm
fonte
0

Será muito dependente do navegador. 100 itens não parece um grande número - espero que você possa ir muito mais alto do que isso. Milhares não devem ser um problema. O que pode ser um problema é o consumo total de memória.

rjmunro
fonte
0

Eu descaradamente puxei alguns conjuntos de dados muito grandes na memória e, embora tenha ficado lento, levou cerca de 15 Mo de dados para cima com cálculos bastante intensos no conjunto de dados. Duvido que você tenha problemas com a memória, a menos que tenha cálculos intensos sobre os dados e muitas linhas. A criação de perfil e benchmarking com diferentes conjuntos de resultados simulados será sua melhor aposta para avaliar o desempenho.

estefgosselina
fonte