Heim > Artikel > Web-Frontend > Wie kann die Leistung des Spread-Operators in Javascript verbessert werden?
In diesem Artikel führen wir einen interessanten Test durch, um zu sehen, wie wir die Leistung des Spread-Operators verbessern können.
Erklären wir zunächst kurz, wie der Spread-Operator in Arrays funktioniert.
Expand-Operatoren, die drei am häufigsten verwendeten, ermöglichen die Erweiterung des Arrays in jeden kleinen Block. Verwenden Sie dann die eckige Klammersyntax []
, um diese kleinen Teile wieder zusammenzusetzen und ein neues Array zu erstellen. []
,重新组装这些小块构造一个新数组。
扩展运算符可以被放置在中括号[]
里面的任何位置。
const numbers = [1, 2, 3]; [0, ...numbers]; // => [0, 1, 2, 3] [0, ...numbers, 4]; // => [0, 1, 2, 3, 4] [...numbers, 4]; // => [1, 2, 3, 4]
回答我们一开始提出的问题,扩展运算符在数组文字中的位置是否可以提高性能?让我们往后继续探究。
在开始性能比较之前,让我们定义两个函数。
第一个是appendToTail()
:
function appendToTail(item, array) { return [...array, item]; } const numbers = [1, 2, 3]; appendToTail(10, numbers); // => [1, 2, 3, 10]
appendToTail()
可以让你在数组的末尾插入一个值。 此函数使用了以下写法[...array, item]
。
第二个是appendToHead()
:
function appendToHead(item, array) { return [item, ...array]; } const numbers = [1, 2, 3]; appendToHead(10, numbers); // => [10, 1, 2, 3]
appendToHead()
是一个纯函数,它返回一个新数组,其中添加的值是插入在原数组的头部。它使用[item, ...array]
。
讲道理就上面这两个函数的表现,没有理由认为这些功能会有不一样的效率。但是事实可能跟我们想象中不一样,下面让我们来继续测试吧。
我用MacBook Pro
在以下3个浏览器的笔记本电脑上测试[... array, item]
和[item, ...array]
,对比两者的性能:
以下是性能测试结果:
正如预期的那样,在Firefox和Safari浏览器中[...array, item]
和[item, ...array]
具有相同的性能。
但是,在Chrome中,[...array, item]
的执行速度比[item, ...array]
快两倍。 这是一个有用的结果。
要在Chrome中提高扩展运算符的性能,请在数组文字的开头使用扩展运算符:
const result = [...array, item];
但另一个问题出现了:这种问题怎么引起的?
从V8引擎的7.2版本之后,为Chrome中的JavaScript执行提供支持,可以对扩展运算符进行新的优化:快速路径优化。
用几句话描述它的工作原理,如下:
如果没有这个优化,当引擎遇到扩展运算符[...iterable, item]时
,它会调用可迭代对象的迭代器iterator.next()
。在每次迭代时,结果数组的内存都会增加,迭代结果会被添加到结果数组中。
但是快速路径优化检测到已知的可迭代(如整数数组)并完全跳过迭代器对象的创建。 然后引擎读取扩展数组的长度,仅为结果数组分配一次内存。 然后通过索引传播数组,将每个项目添加到结果数组中。
快速路径优化会跳过迭代对象的创建,只为结果分配一次内存。 从而性能提高。
快速路径优化适用于以下标准JavaScript数据结构。
数组
const numbers = [1, 2, 3, 4]; [...numbers, 5]; // => [1, 2, 3, 4, 5]
字符串
const message = 'Hi'; [...message, '!']; // => ['H', 'i', '!']
Sets
const colors = new Set(['blue', 'white']); [...colors, 'green']; // => ['blue', 'white', 'green'] [...colors.values(), 'green']; // => ['blue', 'white', 'green'] [...colors.keys(), 'green']; // => ['blue', 'white', 'green']
Maps
在Map对象中,仅支持map.keys()
和map.values()
方法:
const names = new Map([[5, 'five'], [7, 'seven']]); [...names.values(), 'ten']; // => ['five', 'seven', 'ten'] [...names.keys(), 10]; // => [5, 7, 10]
当被扩展的数组位于数组的开头时,由于快速路径优化,您可以获得性能提升。它适用于V8引擎7.2版本(Chrome v72和NodeJS v12附带的特性)。
通过此优化,性能测试显示[... array, item]
的执行速度至少比[item, ...array]
[]
platziert werden. rrreee
Um die Frage zu beantworten, die wir zu Beginn gestellt haben: Verbessert die Positionierung des Spread-Operators innerhalb des Array-Literals die Leistung? Lassen Sie uns weiter erkunden.appendToTail()
: rrreee
appendToTail()
ermöglicht es Ihnen, einen Wert am Ende des Arrays einzufügen. Diese Funktion verwendet die folgende Schreibmethode [...array, item]
. Der zweite ist
rrreeeappendToHead()
:
appendToHead()
ist eine reine Funktion, die ein neues Array zurückgibt, in dem der hinzugefügte Wert in das Original eingefügt wird Array-Kopf. Es verwendet [item, ...array]
.
MacBook Pro
in den folgenden 3 Testen Sie [... array, item]
und [item, ...array]
auf einem Laptop mit einem Browser und vergleichen Sie die Leistung der beiden: 🎜[ ...array, item]
und [item, ...array]
haben die gleiche Leistung. 🎜🎜In Chrome wird [...array, item]
jedoch doppelt so schnell ausgeführt wie [item, ...array]
. Das ist ein nützliches Ergebnis. 🎜🎜Um die Leistung des Spread-Operators in Chrome zu verbessern, verwenden Sie den Spread-Operator am Anfang eines Array-Literals: 🎜rrreee🎜 Aber es stellt sich eine andere Frage: Was verursacht dieses Problem? 🎜🎜 Ab Version 7.2 der V8-Engine, die Unterstützung für die JavaScript-Ausführung in Chrome bietet, kann eine neue Optimierung für den Spread-Operator durchgeführt werden: Schnelle Pfadoptimierung. 🎜🎜Beschreiben Sie die Funktionsweise in ein paar Sätzen wie folgt: 🎜🎜Wenn die Engine ohne diese Optimierung auf den Spread-Operator [...iterable, item]
trifft, ruft sie den iterierbaren Iterator von Objekten auf iterator.next()
. Bei jeder Iteration wird der Speicher des Ergebnisarrays vergrößert und die Iterationsergebnisse werden dem Ergebnisarray hinzugefügt. 🎜🎜Aber die schnelle Pfadoptimierung erkennt bekannte Iterables (wie Ganzzahl-Arrays) und überspringt die Erstellung von Iteratorobjekten vollständig. Die Engine liest dann die Länge des erweiterten Arrays und weist dem resultierenden Array nur einmal Speicher zu. Das Array wird dann per Index weitergegeben, wobei jedes Element dem resultierenden Array hinzugefügt wird. 🎜🎜Die schnelle Pfadoptimierung überspringt die Erstellung von Iterationsobjekten und reserviert nur einmal Speicher für die Ergebnisse. Dadurch wird die Leistung verbessert. 🎜map.keys()
und map.values()
: 🎜rrreee[... array, item]
mindestens doppelt so schnell arbeitet wie [item, ...array]
. 🎜🎜Bitte beachten Sie, dass Fast Path zwar sicherlich nützlich ist, es jedoch empfohlen wird, es dort zu verwenden, wo Leistung wichtig ist oder wenn Sie mit großen Arrays arbeiten. 🎜🎜Denn in den meisten Fällen wird der Endbenutzer bei erzwungener Optimierung höchstwahrscheinlich keinen Unterschied spüren. 🎜🎜Kennen Sie weitere interessante Leistungsoptimierungen in JavaScript, die Sie mir unten in den Kommentaren verraten können? 🎜🎜Wenn der Artikel Ihnen etwas Hilfe oder Inspiration bringen kann, seien Sie bitte nicht geizig mit Ihren Likes und Sternen. Er ist für mich die treibende Kraft und die größte Bestätigung, weiterzumachen🎜🎜🎜Originallink: https://dmitripavlutin .com/javascript-spread-operator -performance-optimization/🎜🎜🎜Weitere Kenntnisse zum Thema Programmierung finden Sie unter: 🎜Programmiervideo🎜! ! 🎜Das obige ist der detaillierte Inhalt vonWie kann die Leistung des Spread-Operators in Javascript verbessert werden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!