Performances Javascript Set vs. Array

C'est peut-être parce que Sets est relativement nouveau sur Javascript, mais je n'ai pas pu trouver un article, sur StackO ou ailleurs, qui parle de la différence de performance entre les deux en Javascript. Alors, quelle est la différence, en termes de performance, entre les deux? Plus précisément, lorsqu'il s'agit de supprimer, d'ajouter et d'itérer.

Ok, j'ai testé l'ajout, l'itération et la suppression d'éléments à la fois d'un tableau et d'un ensemble. J'ai utilisé un test "petit" avec 10 000 éléments et un test "grand" utilisant 100 000 éléments. Voici les résultats.

Ajout d'éléments à une collection

Il semblerait que la méthode du tableau .push soit environ 4 fois plus rapide que la .add réglage .add , quel que soit le nombre d'éléments ajoutés.

Iteration et modification d'éléments dans une collection

Pour cette partie du test, j'ai utilisé une boucle for pour itérer sur le tableau et un for of boucle pour itérer sur l'ensemble. Encore une fois, l'itération sur le tableau était plus rapide. Cette fois, il semble que ce soit exponentiellement, car il a fallu deux fois plus de temps pendant les tests «petits» et presque quatre fois plus longtemps lors des «grands» tests.

Suppression d'éléments d'une collection

Maintenant c'est là que ça devient intéressant. J'ai utilisé une combinaison d'une boucle for et de .splice pour supprimer certains éléments du tableau et j'ai utilisé for of et .delete pour supprimer certains éléments de l'ensemble. Pour les "petits" tests, il était environ trois fois plus rapide pour supprimer les éléments de l'ensemble (2,6 ms vs 7,1 ms), mais les choses ont changé drastiquement pour le "grand" test où il a fallu 1955,1 ms pour supprimer des éléments du tableau alors qu'il était seulement A pris 83,6 ms pour les supprimer de l'ensemble, 23 fois plus vite.

Conclusions

À 10k éléments, les deux tests ont eu des temps comparables (tableau: 16.6 ms, ensemble: 20.7 ms) mais en cas d'éléments de 100k, l'ensemble était le vainqueur clair (tableau: 1974.8 ms, set: 83.6 ms) mais uniquement en raison de l'élimination opération. Sinon, le tableau était plus rapide. Je ne pouvais pas dire exactement pourquoi.

J'ai joué avec des scénarios hybrides où un tableau a été créé et rempli, puis converti en un ensemble où certains éléments seraient supprimés. L'ensemble serait alors reconverti dans un tableau. Bien que cela entraîne des performances beaucoup plus élevées que la suppression des éléments dans le tableau, le temps de traitement supplémentaire nécessaire pour transférer vers et à partir d'un ensemble dépasse les gains de peuplement d'un tableau au lieu d'un ensemble. À la fin, il est plus rapide de ne traiter qu'un ensemble. Pourtant, il est intéressant de noter que si l'on choisit d'utiliser un tableau en tant que collecte de données pour certaines grandes données qui ne comportent pas de doublons, il pourrait être avantageux pour les performances, s'il est nécessaire d'enlever plusieurs éléments en un seul Opération, pour convertir le tableau en un ensemble, effectuer l'opération de suppression et convertir le jeu en un tableau.

Code de tableau:

 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.") 
 console.time("set") var s = new Set() for(var i = 0; i < 10000; i++) s.add(Math.random()) s.forEach(function(e){ s.delete(e) }) console.timeEnd("set") console.time("array") var s = new Array() for(var i = 0; i < 10000; i++) s.push(Math.random()) s.forEach(function(e,i){ s.splice(i) }) console.timeEnd("array") 

Ces trois opérations sur les articles de 10K m'ont donné:

 set: 7.787ms array: 2.388ms