Mam model z prawdopodobnie tysiącami obiektów. Zastanawiałem się, jaki byłby najskuteczniejszy sposób przechowywania ich i pobierania pojedynczego obiektu, gdy mam jego identyfikator. Identyfikatory to długie liczby.
Więc to są 2 opcje, o których myślałem. w opcji pierwszej jest to prosta tablica z rosnącym indeksem. w opcji 2 jest to tablica asocjacyjna i być może obiekt, jeśli ma znaczenie. Moje pytanie brzmi, który z nich jest bardziej wydajny, gdy najczęściej potrzebuję pobrać pojedynczy obiekt, ale czasami też przechodzę przez niego w pętli i sortuję.
Opcja pierwsza z tablicą nieasocjacyjną:
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];
}
}
Opcja druga z tablicą asocjacyjną:
var a = []; // maybe {} makes a difference?
a[29938] = {id: 29938, name: 'name1'};
a[32994] = {id: 32994, name: 'name1'};
function getObject(id) {
return a[id];
}
Aktualizacja:
OK, rozumiem, że użycie tablicy w drugiej opcji jest wykluczone. Zatem w linii deklaracji druga opcja naprawdę powinna brzmieć: var a = {};
a jedyne pytanie brzmi: co działa lepiej w pobieraniu obiektu o podanym identyfikatorze: tablica lub obiekt, w którym id jest kluczem.
a także, czy odpowiedź ulegnie zmianie, jeśli będę musiał wielokrotnie sortować listę?
źródło
Odpowiedzi:
Krótka wersja: tablice są przeważnie szybsze niż obiekty. Ale nie ma 100% poprawnego rozwiązania.
Aktualizacja 2017 - Test i wyniki
Oryginalny post - wyjaśnienie
Twoje pytanie zawiera nieporozumienia.
W JavaScript nie ma tablic asocjacyjnych. Tylko tablice i obiekty.
Oto tablice:
To też jest tablica:
Zasadniczo jest to tablica z dziurami, ponieważ każda tablica ma ciągłe indeksowanie. Jest wolniejszy niż tablice bez otworów. Ale ręczne iterowanie po tablicy jest jeszcze wolniejsze (głównie).
To jest obiekt:
Oto test wydajności obejmujący trzy możliwości:
Tablica odnośników a tablica dziurawych vs test wydajności obiektu
Doskonała lektura na te tematy w Smashing Magazine: Pisanie szybko wydajnego pamięciowo JavaScript
źródło
if (a1[i].id = id) result = a1[i];
Powinien być:if (a1[i].id === id) result = a1[i];
Test http://jsperf.com/array-vs-object-performance/37 koryguje toTo wcale nie jest kwestia wydajności, ponieważ tablice i obiekty działają bardzo różnie (lub przynajmniej powinny). Tablice mają ciągły indeks
0..n
, podczas gdy obiekty odwzorowują dowolne klucze na dowolne wartości. Jeżeli Państwo chcą dostarczyć konkretne klawisze, jedynym wyborem jest obiektem. Jeśli nie dbasz o klucze, to jest to tablica.Jeśli spróbujesz ustawić dowolne (numeryczne) klucze w tablicy, naprawdę masz utratę wydajności , ponieważ behawioralnie tablica wypełni wszystkie indeksy pomiędzy:
(Zauważ, że tablica w rzeczywistości nie zawiera 99
undefined
wartości, ale będzie się zachowywać w ten sposób, ponieważ w pewnym momencie [powinieneś] iterować tablicę.)Literały obu opcji powinny bardzo jasno określać, w jaki sposób można ich używać:
źródło
user_id
„vs” posiadającym klucze, ponieważuser_id
stąd dostęp do obiektu użytkownika można uzyskać używającuser_id
jako klucza? Który z nich jest lepszy pod względem wydajności? Wszelkie sugestie na ten temat są mile widziane :)W ES6 najbardziej wydajnym sposobem byłoby użycie mapy.
Możesz korzystać z funkcji ES6 już dziś, używając podkładki ( https://github.com/es-shims/es6-shim ).
Wydajność będzie się różnić w zależności od przeglądarki i scenariusza. Ale oto jeden przykład, gdzie
Map
jest najbardziej wydajny: https://jsperf.com/es6-map-vs-object-properties/2ODNIESIENIE https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Map
źródło
efficiency
.W NodeJS, jeśli znasz
ID
, pętla w tablicy jest bardzo powolna w porównaniu zobject[ID]
.A wyniki:
Nawet jeśli szukany identyfikator jest pierwszym w tablicy / obiekcie:
źródło
Próbowałem dosłownie przenieść to do następnego wymiaru.
Biorąc pod uwagę dwuwymiarową tablicę, w której osie x i y mają zawsze tę samą długość, czy szybciej:
a) wyszukaj komórkę, tworząc dwuwymiarową tablicę i wyszukując pierwszy indeks, po którym następuje drugi indeks, tj .:
lub
b) utwórz obiekt z ciągiem reprezentującym współrzędne x i y, a następnie wykonaj pojedyncze wyszukiwanie na tym obiekcie, tj .:
Wynik:
okazuje się, że wykonanie dwóch wyszukiwań indeksów numerycznych w tablicach jest znacznie szybsze niż jedno wyszukiwanie właściwości obiektu.
Wyniki tutaj:
http://jsperf.com/arr-vs-obj-lookup-2
źródło
To zależy od użytkowania. Jeśli sprawa dotyczy obiektów wyszukiwania jest bardzo szybsza.
Oto przykład Plunkera do testowania wydajności wyszukiwania tablic i obiektów.
https://plnkr.co/edit/n2expPWVmsdR3zmXvX4C?p=preview
Zobaczysz to; Wyszukując 5000 elementów w kolekcji tablic o długości 5000 , przejmij
3000
milisekonyJednak wyszukiwanie 5.000 elementów w obiekcie ma 5.000 właściwości, bierze tylko
2
lub3
milisekonyRównież tworzenie drzewa obiektów nie robi dużej różnicy
źródło
Miałem podobny problem, z którym mam do czynienia, gdy muszę przechowywać świece na żywo ze źródła zdarzeń ograniczonego do x elementów. Mógłbym przechowywać je w obiekcie, w którym znacznik czasu każdej świecy działałby jako klucz, a sama świeca byłaby wartością. Inną możliwością było to, że mógłbym przechowywać go w tablicy, w której każdy element był samą świecą. Jednym z problemów związanych ze świecami na żywo jest to, że wysyłają aktualizacje z tym samym znacznikiem czasu, w którym najnowsza aktualizacja zawiera najnowsze dane, dlatego albo aktualizujesz istniejący element, albo dodajesz nowy. Oto dobry punkt odniesienia, który próbuje połączyć wszystkie 3 możliwości. Tablice w poniższym rozwiązaniu są średnio co najmniej 4x szybsze. Zapraszam do gry
Wniosek 10 jest tutaj granicą
źródło
Jeśli masz posortowaną tablicę, możesz przeprowadzić wyszukiwanie binarne i jest to znacznie szybsze niż wyszukiwanie obiektów, możesz zobaczyć moją odpowiedź tutaj:
Jak szybciej wyszukiwać w posortowanej tablicy przy użyciu JavaScript
źródło