Ok, przetestowałem dodawanie, iterowanie i usuwanie elementów zarówno z tablicy, jak i zestawu. Przeprowadziłem „mały” test, używając 10 000 elementów i „duży” test, używając 100 000 elementów. Oto wyniki.
Dodawanie elementów do kolekcji
Wydawałoby się, że .push
metoda tablicowa jest około 4 razy szybsza niż .add
metoda set, niezależnie od ilości dodawanych elementów.
Iterowanie i modyfikowanie elementów w kolekcji
W tej części testu użyłem for
pętli do iteracji po tablicy i for of
pętli do iteracji po zestawie. Ponownie, iterowanie po tablicy było szybsze. Tym razem wydawać by się mogło, że jest to wykładnicze, ponieważ podczas testów „małych” trwało to dwa razy dłużej, a podczas testów „dużych” prawie czterokrotnie dłużej.
Usuwanie elementów z kolekcji
Teraz robi się interesująco. Użyłem kombinacji for
pętli i .splice
usunięcia niektórych elementów z tablicy oraz użyłem for of
i .delete
usunąłem niektóre elementy z zestawu. W przypadku „małych” testów usuwanie elementów z zestawu było około trzy razy szybsze (2,6 ms w porównaniu z 7,1 ms), ale sytuacja zmieniła się drastycznie w przypadku testu „dużego”, w którym usunięcie elementów z tablicy zajęło tylko 1955,1 ms. usunięcie ich z zestawu zajęło 83,6 ms, czyli 23 razy szybciej.
Wnioski
Przy 10 tys. Elementów oba testy działały porównywalnie (tablica: 16,6 ms, zestaw: 20,7 ms), ale przy 100 tys. Elementów zestaw był wyraźnym zwycięzcą (tablica: 1974,8 ms, zestaw: 83,6 ms), ale tylko ze względu na usunięcie operacja. W przeciwnym razie tablica była szybsza. Nie potrafię dokładnie powiedzieć, dlaczego tak jest.
Bawiłem się niektórymi scenariuszami hybrydowymi, w których tablica została utworzona i zapełniona, a następnie przekształcona w zestaw, w którym niektóre elementy zostałyby usunięte, a następnie zestaw zostałby ponownie przekształcony w tablicę. Chociaż da to znacznie lepszą wydajność niż usuwanie elementów w tablicy, dodatkowy czas przetwarzania potrzebny do przesłania do iz zestawu przeważa nad korzyściami wynikającymi z zapełnienia tablicy zamiast zestawu. W końcu szybciej jest zajmować się tylko zestawem. Mimo to jest interesującym pomysłem, że jeśli zdecydujesz się użyć tablicy jako zbioru danych dla niektórych dużych zbiorów danych, które nie mają duplikatów, może to być korzystne pod względem wydajności, jeśli kiedykolwiek zajdzie potrzeba usunięcia wielu elementów w jednym operacja, aby przekonwertować tablicę na zestaw, wykonać operację usuwania i przekonwertować zestaw z powrotem na tablicę.
Kod tablicy:
var timer = function(name) {
var start = new Date();
return {
stop: function() {
var end = new Date();
var time = end.getTime() - start.getTime();
console.log('Timer:', name, 'finished in', time, 'ms');
}
}
};
var getRandom = function(min, max) {
return Math.random() * (max - min) + min;
};
var lastNames = ['SMITH', 'JOHNSON', 'WILLIAMS', 'JONES', 'BROWN', 'DAVIS', 'MILLER', 'WILSON', 'MOORE', 'TAYLOR', 'ANDERSON', 'THOMAS'];
var genLastName = function() {
var index = Math.round(getRandom(0, lastNames.length - 1));
return lastNames[index];
};
var sex = ["Male", "Female"];
var genSex = function() {
var index = Math.round(getRandom(0, sex.length - 1));
return sex[index];
};
var Person = function() {
this.name = genLastName();
this.age = Math.round(getRandom(0, 100))
this.sex = "Male"
};
var genPersons = function() {
for (var i = 0; i < 100000; i++)
personArray.push(new Person());
};
var changeSex = function() {
for (var i = 0; i < personArray.length; i++) {
personArray[i].sex = genSex();
}
};
var deleteMale = function() {
for (var i = 0; i < personArray.length; i++) {
if (personArray[i].sex === "Male") {
personArray.splice(i, 1)
i--
}
}
};
var t = timer("Array");
var personArray = [];
genPersons();
changeSex();
deleteMale();
t.stop();
console.log("Done! There are " + personArray.length + " persons.")
Ustaw kod:
var timer = function(name) {
var start = new Date();
return {
stop: function() {
var end = new Date();
var time = end.getTime() - start.getTime();
console.log('Timer:', name, 'finished in', time, 'ms');
}
}
};
var getRandom = function (min, max) {
return Math.random() * (max - min) + min;
};
var lastNames = ['SMITH','JOHNSON','WILLIAMS','JONES','BROWN','DAVIS','MILLER','WILSON','MOORE','TAYLOR','ANDERSON','THOMAS'];
var genLastName = function() {
var index = Math.round(getRandom(0, lastNames.length - 1));
return lastNames[index];
};
var sex = ["Male", "Female"];
var genSex = function() {
var index = Math.round(getRandom(0, sex.length - 1));
return sex[index];
};
var Person = function() {
this.name = genLastName();
this.age = Math.round(getRandom(0,100))
this.sex = "Male"
};
var genPersons = function() {
for (var i = 0; i < 100000; i++)
personSet.add(new Person());
};
var changeSex = function() {
for (var key of personSet) {
key.sex = genSex();
}
};
var deleteMale = function() {
for (var key of personSet) {
if (key.sex === "Male") {
personSet.delete(key)
}
}
};
var t = timer("Set");
var personSet = new Set();
genPersons();
changeSex();
deleteMale();
t.stop();
console.log("Done! There are " + personSet.size + " persons.")