Eu tenho um modelo com possivelmente milhares de objetos. Eu queria saber qual seria a maneira mais eficiente de armazená-los e recuperar um único objeto, uma vez que eu tenha o seu ID. Os IDs são números longos.
Então, essas são as 2 opções que eu estava pensando. na opção um, é uma matriz simples com um índice incremental. na opção 2, é uma matriz associativa e talvez um objeto, se faz alguma diferença. Minha pergunta é qual deles é mais eficiente, quando eu geralmente preciso recuperar um único objeto, mas às vezes também os percorre e ordena.
Opção um com matriz não associativa:
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];
}
}
Opção dois com matriz associativa:
var a = []; // maybe {} makes a difference?
a[29938] = {id: 29938, name: 'name1'};
a[32994] = {id: 32994, name: 'name1'};
function getObject(id) {
return a[id];
}
Atualizar:
OK, acho que o uso de uma matriz na segunda opção está fora de questão. Portanto, a linha de declaração da segunda opção deve ser realmente:var a = {};
e a única questão é: o que tem um desempenho melhor na recuperação de um objeto com um determinado ID: uma matriz ou um objeto em que o ID é a chave.
e também, a resposta será alterada se tiver que classificar a lista várias vezes?
fonte
Respostas:
A versão curta: as matrizes são mais rápidas que os objetos. Mas não há solução 100% correta.
Atualização 2017 - Teste e resultados
Post original - Explicação
Existem alguns conceitos errados na sua pergunta.
Não há matrizes associativas em Javascript. Somente matrizes e objetos.
Estas são matrizes:
Também é uma matriz:
É basicamente um array com buracos, porque todo array tem indexação contínua. É mais lento que as matrizes sem furos. Mas iterar manualmente através da matriz é ainda mais lento (principalmente).
Este é um objeto:
Aqui está um teste de desempenho de três possibilidades:
Matriz de pesquisa vs Matriz Holey x Teste de desempenho de objeto
Uma excelente leitura sobre esses tópicos na Smashing Magazine: Escrevendo JavaScript com eficiência de memória rápida
fonte
if (a1[i].id = id) result = a1[i];
Deve ser:if (a1[i].id === id) result = a1[i];
Teste http://jsperf.com/array-vs-object-performance/37 corrige queNão é realmente uma questão de desempenho, já que matrizes e objetos funcionam de maneira muito diferente (ou deveriam, pelo menos). As matrizes têm um índice contínuo
0..n
, enquanto os objetos mapeiam chaves arbitrárias para valores arbitrários. Se você deseja fornecer chaves específicas, a única opção é um objeto. Se você não se importa com as chaves, é uma matriz.Se você tentar definir chaves arbitrárias (numéricas) em uma matriz, você realmente terá uma perda de desempenho , pois, comportamentalmente, a matriz preencherá todos os índices intermediários:
(Observe que a matriz, na verdade, não contém 99
undefined
valores, mas se comportará dessa maneira, já que você deveria iterar a matriz em algum momento.)Os literais para ambas as opções devem deixar muito claro como eles podem ser usados:
fonte
user_id
" vs "que possui chaves,user_id
portanto, o objeto do usuário pode ser acessado usandouser_id
como chave"? Qual é o melhor em termos de desempenho? Todas as sugestões sobre isso são apreciadas :)Com o ES6, a maneira mais eficiente seria usar um mapa.
Você pode usar os recursos do ES6 hoje usando um calço ( https://github.com/es-shims/es6-shim ).
O desempenho varia de acordo com o navegador e o cenário. Mas aqui está um exemplo em que o
Map
desempenho é mais alto: https://jsperf.com/es6-map-vs-object-properties/2REFERÊNCIA https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map
fonte
efficiency
.No NodeJS, se você souber
ID
, o loop pelo array é muito lento comparado aobject[ID]
.E os resultados:
Mesmo se o ID de busca for o primeiro na matriz / objeto:
fonte
Tentei levar isso para a próxima dimensão, literalmente.
Dada uma matriz bidimensional, na qual os eixos xey são sempre do mesmo comprimento, é mais rápido:
a) procure a célula criando uma matriz bidimensional e procurando o primeiro índice, seguido pelo segundo índice, ou seja:
ou
b) crie um objeto com uma representação de string das coordenadas xey, e faça uma única pesquisa nesse objeto, ou seja:
Resultado:
verifica-se que é muito mais rápido fazer duas pesquisas de índice numérico nas matrizes do que uma pesquisa de propriedade no objeto.
Resultados aqui:
http://jsperf.com/arr-vs-obj-lookup-2
fonte
Depende do uso. Se o caso for objetos de pesquisa é muito mais rápido.
Aqui está um exemplo do Plunker para testar o desempenho de pesquisas de matriz e objeto.
https://plnkr.co/edit/n2expPWVmsdR3zmXvX4C?p=preview
Você verá isso; Procurando 5.000 itens na coleção de matriz de 5.000 comprimentos, ocupe
3000
milissegundosNo entanto, procurar 5.000 itens no objeto tem 5.000 propriedades, apenas take
2
ou3
milissegundosTambém criar árvore de objetos não faz muita diferença
fonte
Eu tive um problema semelhante que estou enfrentando, onde preciso armazenar candlesticks ao vivo de uma fonte de evento limitada a x itens. Eu poderia armazená-los em um objeto em que o carimbo de data e hora de cada vela atuaria como a chave e a própria vela atuaria como o valor. Outra possibilidade era que eu pudesse armazená-lo em uma matriz onde cada item fosse a própria vela. Um problema das velas ativas é que elas continuam enviando atualizações no mesmo registro de data e hora em que a atualização mais recente contém os dados mais recentes; portanto, você atualiza um item existente ou adiciona um novo. Então, aqui está uma boa referência que tenta combinar todas as três possibilidades. As matrizes na solução abaixo são pelo menos 4x mais rápidas, em média. Sinta-se livre para jogar
Conclusão 10 é o limite aqui
fonte
Se você tiver uma matriz classificada, poderá fazer uma pesquisa binária e isso é muito mais rápido que uma pesquisa de objeto, pode ver a minha resposta aqui:
Como pesquisar mais rapidamente em uma matriz classificada usando Javascript
fonte