Heim > Artikel > Web-Frontend > Ausführliche Erklärung, wie man Set verwendet, um die Leistung von JS-Code zu verbessern
Ich bin sicher, dass viele Entwickler bei den grundlegenden globalen Objekten hängen bleiben: Zahlen, Zeichenfolgen, Objekte, Arrays und Boolesche Werte. Für viele Anwendungsfälle werden diese benötigt. Wenn Sie jedoch möchten, dass Ihr Code so schnell und skalierbar wie möglich ist, sind diese Grundtypen nicht immer gut genug.
In diesem Artikel besprechen wir, wie das Set
-Objekt in JS Code schneller macht – insbesondere skalierbar und praktisch. Es gibt viele Überschneidungen in der Funktionsweise von Array
und Set
. Allerdings hat die Verwendung von Set
im Hinblick auf die Codeausführungsgeschwindigkeit einen Vorteil gegenüber Array
. Set
对象如何让代码更快— 特别扩展性方便。 Array
和Set
工作方式存在大量的交叉。但是使用Set
会比Array
在代码运行速度更有优势。
最根本的区别是数组是一个索引集合,这说明数组中的数据值按索引排序。
const arr = [A, B, C, D]; console.log(arr.indexOf(A)); // Result: 0 console.log(arr.indexOf(C)); // Result: 2
相比之下,set
是一个键的集合。set
不使用索引,而是使用键对数据排序。set
中的元素按插入顺序是可迭代的,它不能包含任何重复的数据。换句话说,set
中的每一项都必须是惟一的。
set
相对于数组有几个优势,特别是在运行时间方面:
indexOf()
或includes()
检查数组中的项是否存在是比较慢的。Set
中,可以根据每项的的 value
来删除该项。在数组中,等价的方法是使用基于元素的索引的splice()
。与前一点一样,依赖于索引的速度很慢。indexOf()
或 includes()
来查找值 NaN
,而 Set
可以保存此值。Set
对象只存储惟一的值,如果不想有重复项存在,相对于数组的一个显著优势,因为数组需要额外的代码来处理重复。数组用来搜索元素的方法时间复杂度为0(N)
。换句话说,运行时间的增长速度与数据大小的增长速度相同。
相比之下,Set
用于搜索、删除和插入元素的方法的时间复杂度都只有O(1)
,这意味着数据的大小实际上与这些方法的运行时间无关。
虽然运行时间可能会有很大差异,具体取决于所使用的系统,所提供数据的大小以及其他变量,但我希望我的测试结果能够让你真实地了解Set
的速度。 我将分享三个简单的测试和我得到的结果。
在运行任何测试之前,创建一个数组和一个 Set,每个数组和 Set 都有100万个元素。为了简单起见,我从0
开始,一直数到999999
。
let arr = [], set = new Set(), n = 1000000; for (let i = 0; i < n; i++) { arr.push(i); set.add(i); }
我们搜索数字123123
let result; console.time('Array'); result = arr.indexOf(123123) !== -1; console.timeEnd('Array'); console.time('Set'); result = set.has(123123); console.timeEnd('Set');
Set
速度快了7.54
倍
console.time('Array'); arr.push(n); console.timeEnd('Array'); console.time('Set'); set.add(n); console.timeEnd('Set');
Set
速度快了6.73
倍
最后,删除一个元素,由于数组没有内置方法,首先先创建一个辅助函数:
const deleteFromArr = (arr, item) => { let index = arr.indexOf(item); return index !== -1 && arr.splice(index, 1); };
这是测试的代码:
console.time('Array'); deleteFromArr(arr, n); console.timeEnd('Array'); console.time('Set'); set.delete(n); console.timeEnd('Set');
Set
速度快了74.13
倍
总的来说,我们可以看到,使用Set
极大地改善运行时间。再来看看一些Set
有用的实际例子。
如果想快速地从数组中删除重复的值,可以将其转换为一个 Set
。这是迄今为止过滤惟一值最简洁的方法:
const duplicateCollection = ['A', 'B', 'B', 'C', 'D', 'B', 'C']; // 将数组转换为 Set let uniqueCollection = new Set(duplicateCollection); console.log(uniqueCollection) // Result: Set(4) {"A", "B", "C", "D"} // 值保存在数组中 let uniqueCollection = [...new Set(duplicateCollection)]; console.log(uniqueCollection) // Result: ["A", "B", "C", "D"]
问题:
给定一个整数无序数组和变量 sum
,如果存在数组中任意两项和使等于 sum
的值,则返回true
。否则,返回false
。例如,数组[3,5,1,4]
和 sum = 9
,函数应该返回true
,因为4 + 5 = 9
。
解答
解决这个问题的一个很好的方法是遍历数组,创建 Set
const findSum = (arr, val) => { let searchValues = new Set(); searchValues.add(val - arr[0]); for (let i = 1, length = arr.length; i < length; i++) { let searchVal = val - arr[i]; if (searchValues.has(arr[i])) { return true; } else { searchValues.add(searchVal); } }; return false; };🎜Im Gegensatz dazu ist
set
eine Sammlung von Schlüsseln. set
verwendet keine Indizes, sondern Schlüssel zum Sortieren der Daten. Die Elemente in set
sind in der Einfügereihenfolge iterierbar und dürfen keine doppelten Daten enthalten. Mit anderen Worten: Jedes Element im set
muss eindeutig sein. 🎜set
hat mehrere Vorteile gegenüber Arrays, insbesondere im Hinblick auf die Laufzeit: 🎜indexOf()
oder includes()
zum Überprüfen, ob ein Element in einem Array vorhanden ist, ist langsamer. Set
können Sie jedes Element basierend auf seinem Wert
löschen. In Arrays ist die äquivalente Methode splice()
mit elementbasierter Indizierung. Wie im vorherigen Punkt ist es langsam, sich auf Indizes zu verlassen. indexOf()
oder includes()
kann nicht verwendet werden, um den Wert NaN zu finden. code> > und <code>Set
können diesen Wert speichern.
Set
-Objekte speichern nur eindeutige Werte. Wenn Sie nicht möchten, dass Duplikate existieren, ist dies ein wesentlicher Vorteil gegenüber Arrays, da Arrays Für die Duplizierung ist zusätzlicher Code erforderlich. 0(N)
. Mit anderen Worten: Die Laufzeit wächst im gleichen Maße wie die Datengröße. 🎜🎜Im Gegensatz dazu beträgt die zeitliche Komplexität der Methoden von Set
zum Suchen, Löschen und Einfügen von Elementen nur O(1)
, was bedeutet, dass die Größe der Daten beträgt hat eigentlich nichts mit der Laufzeit dieser Methoden zu tun. 🎜Set
vermitteln Geschwindigkeit. Ich werde drei einfache Tests und die Ergebnisse, die ich erhalten habe, mit Ihnen teilen. 🎜0
und zähle bis 999999
. 🎜const findSum = (arr, sum) => arr.some((set => n => set.has(n) || !set.add(sum - n))(new Set));
123123
🎜rrreeeSet
ist 7,54
mal schneller🎜Set
ist schnell6,73 mal 🎜Set
ist 74,13
mal schnell 🎜🎜Insgesamt können wir sehen, dass die Verwendung von Set
die Laufzeit erheblich verbessert. Schauen wir uns einige praktische Beispiele an, bei denen Set
nützlich ist. 🎜Set
. Dies ist bei weitem die sauberste Möglichkeit, eindeutige Werte zu filtern: 🎜rrreeesum
, wenn es zwei beliebige Elemente im Array gibt und die Summe gleich sum
Wert, gibt true
zurück. Andernfalls wird false
zurückgegeben. Beispielsweise sollte die Funktion für das Array [3,5,1,4]
und sum = 9
true
zurückgeben, weil 4 + 5 = 9
. 🎜🎜Antwort🎜🎜Eine gute Möglichkeit, dieses Problem zu lösen, besteht darin, das Array zu durchlaufen und einen Satz
zu erstellen, um die relativen Unterschiede zu speichern. 🎜当我们遇到3
时,我们可以把6
加到Set
中, 因为我们知道我们需要找到9
的和。然后,每当我们接触到数组中的新值时,我们可以检查它是否在 Set
中。当遇到5
时,在 Set 加上4。最后,当我们最终遇到4
时,可以在Set
中找到它,就返回true
。
const findSum = (arr, val) => { let searchValues = new Set(); searchValues.add(val - arr[0]); for (let i = 1, length = arr.length; i < length; i++) { let searchVal = val - arr[i]; if (searchValues.has(arr[i])) { return true; } else { searchValues.add(searchVal); } }; return false; };
简洁的版本:
const findSum = (arr, sum) => arr.some((set => n => set.has(n) || !set.add(sum - n))(new Set));
因为Set.prototype.has()
的时间复杂度仅为O(1)
,所以使用 Set 来代替数组,最终使整个解决方案的线性运行时为O(N)
。
如果使用 Array.prototype.indexOf()
或Array.prototype.includes()
,它们的时间复杂度都为 O(N),则总运行时间将为O(N²)
,慢得多!
原文地址:https://medium.com/@bretcameron/how-to-make-your-code-faster-using-javascript-sets-b432457a4a77
更多编程相关知识,请访问:编程入门!!
Das obige ist der detaillierte Inhalt vonAusführliche Erklärung, wie man Set verwendet, um die Leistung von JS-Code zu verbessern. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!