Heim  >  Artikel  >  Web-Frontend  >  Ausführliche Erklärung, wie man Set verwendet, um die Leistung von JS-Code zu verbessern

Ausführliche Erklärung, wie man Set verwendet, um die Leistung von JS-Code zu verbessern

青灯夜游
青灯夜游nach vorne
2021-01-14 19:01:311930Durchsuche

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对象如何让代码更快— 特别扩展性方便。 ArraySet工作方式存在大量的交叉。但是使用Set会比Array在代码运行速度更有优势。

Set 有何不同

最根本的区别是数组是一个索引集合,这说明数组中的数据值按索引排序。

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()。与前一点一样,依赖于索引的速度很慢。
  • 保存 NaN:不能使用indexOf()includes() 来查找值 NaN,而 Set 可以保存此值。
  • 删除重复项Set对象只存储惟一的值,如果不想有重复项存在,相对于数组的一个显著优势,因为数组需要额外的代码来处理重复。

时间复杂度?

数组用来搜索元素的方法时间复杂度为0(N)。换句话说,运行时间的增长速度与数据大小的增长速度相同。

相比之下,Set用于搜索、删除和插入元素的方法的时间复杂度都只有O(1),这意味着数据的大小实际上与这些方法的运行时间无关。

Set 究竟有多快?

虽然运行时间可能会有很大差异,具体取决于所使用的系统,所提供数据的大小以及其他变量,但我希望我的测试结果能够让你真实地了解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);
}

测试1:查找元素

我们搜索数字123123

let result;
console.time(&#39;Array&#39;); 
result = arr.indexOf(123123) !== -1; 
console.timeEnd(&#39;Array&#39;);
console.time(&#39;Set&#39;); 
result = set.has(123123); 
console.timeEnd(&#39;Set&#39;);
  • Array: 0.173ms
  • Set: 0.023ms

Set 速度快了7.54

测试2:添加元素

console.time(&#39;Array&#39;); 
arr.push(n);
console.timeEnd(&#39;Array&#39;);
console.time(&#39;Set&#39;); 
set.add(n);
console.timeEnd(&#39;Set&#39;);
  • Array: 0.018ms
  • Set: 0.003ms

Set 速度快了6.73

测试3:删除元素

最后,删除一个元素,由于数组没有内置方法,首先先创建一个辅助函数:

const deleteFromArr = (arr, item) => {
  let index = arr.indexOf(item);
  return index !== -1 && arr.splice(index, 1);
};

这是测试的代码:

console.time(&#39;Array&#39;); 
deleteFromArr(arr, n);
console.timeEnd(&#39;Array&#39;);
console.time(&#39;Set&#39;); 
set.delete(n);
console.timeEnd(&#39;Set&#39;);
  • Array: 1.122ms
  • Set: 0.015ms

Set 速度快了74.13

总的来说,我们可以看到,使用Set 极大地改善运行时间。再来看看一些Set有用的实际例子。

案例1:从数组中删除重复的值

如果想快速地从数组中删除重复的值,可以将其转换为一个 Set。这是迄今为止过滤惟一值最简洁的方法:

const duplicateCollection = [&#39;A&#39;, &#39;B&#39;, &#39;B&#39;, &#39;C&#39;, &#39;D&#39;, &#39;B&#39;, &#39;C&#39;];
// 将数组转换为 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"]

案例2:谷歌面试问题

问题:

给定一个整数无序数组和变量 sum,如果存在数组中任意两项和使等于 sum 的值,则返回true。否则,返回false。例如,数组[3,5,1,4]sum = 9,函数应该返回true,因为4 + 5 = 9

解答

解决这个问题的一个很好的方法是遍历数组,创建 Set

Was ist der Unterschied zwischen Set

Der grundlegendste Unterschied besteht darin, dass das Array eine indizierte Sammlung ist, was bedeutet, dass die Datenwerte im Array nach Index sortiert sind. 🎜
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. 🎜

Was sind die Hauptvorteile

🎜set hat mehrere Vorteile gegenüber Arrays, insbesondere im Hinblick auf die Laufzeit: 🎜
  • Elemente anzeigen : Die Verwendung von indexOf() oder includes() zum Überprüfen, ob ein Element in einem Array vorhanden ist, ist langsamer.
  • Elemente löschen: In 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.
  • Einsparung von NaN: indexOf() oder includes() kann nicht verwendet werden, um den Wert NaN zu finden. code> > und <code>Set können diesen Wert speichern.
  • Duplikate löschen: 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.

Zeitkomplexität?

🎜Die zeitliche Komplexität der Methode zur Suche nach Elementen in einem Array beträgt 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. 🎜

Wie schnell ist Set?

🎜Während die Laufzeiten je nach verwendetem System, der Größe der bereitgestellten Daten und anderen Variablen stark variieren können, hoffe ich, dass meine Testergebnisse Ihnen eine realistische Vorstellung von Set vermitteln Geschwindigkeit. Ich werde drei einfache Tests und die Ergebnisse, die ich erhalten habe, mit Ihnen teilen. 🎜

Vorbereitung auf Tests

🎜 Bevor Sie einen Test ausführen, erstellen Sie einen Array und ein Set, jedes Array und Set hat 1 Million Elemente. Der Einfachheit halber beginne ich bei 0 und zähle bis 999999. 🎜
const findSum = (arr, sum) =>
  arr.some((set => n => set.has(n) || !set.add(sum - n))(new Set));

Test 1: Find Element

🎜Wir suchen nach der Zahl 123123🎜rrreee
  • Array: 0,173ms li>
  • Set: 0,023 ms
🎜Set ist 7,54 mal schneller🎜

Test 2: Element hinzufügen

rrreee
  • Array: 0,018 ms
  • Set: 0,003 ms
🎜Set ist schnell6,73 mal 🎜

Test 3: Element löschen

🎜Da das Array keine integrierte Methode hat, erstellen Sie zunächst einen Helfer Funktion: 🎜 rrreee🎜Das ist der Testcode:🎜rrreee
  • Array: 1.122ms
  • Set: 0.015ms
🎜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. 🎜

Fall 1: Doppelte Werte aus Array entfernen

🎜Wenn Um doppelte Werte schnell aus einem Array zu entfernen, konvertieren Sie es in ein Set. Dies ist bei weitem die sauberste Möglichkeit, eindeutige Werte zu filtern: 🎜rrreee

Case 2: Google Interview Questions🎜Frage:🎜🎜Angenommen ein ungeordnetes Array von Ganzzahlen und die Variable sum, 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!

Stellungnahme:
Dieser Artikel ist reproduziert unter:cnblogs.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen