JavaScriptのスプレッド演算子のパフォーマンスを向上させるにはどうすればよいですか?

青灯夜游
リリース: 2021-02-25 10:14:15
転載
1804 人が閲覧しました

JavaScriptのスプレッド演算子のパフォーマンスを向上させるにはどうすればよいですか?

この記事では、スプレッド演算子のパフォーマンスをどのように改善できるかを確認する興味深いテストを実施します。

スプレッド演算子が配列でどのように機能するかを簡単に紹介することから始めましょう。

展開演算子 (一般的に使用される 3 つ) を使用すると、配列を小さなブロックごとに展開できます。次に、角かっこ構文 [] を使用して、これらの小さな部分を再組み立てして、新しい配列を構築します。

スプレッド演算子は、角括弧 [] 内のどこにでも配置できます。

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]
ログイン後にコピー

最初の質問に答えると、配列リテラル内にスプレッド演算子を配置するとパフォーマンスが向上しますか?さらに詳しく調べてみましょう。

先頭関数と末尾関数に追加

パフォーマンスの比較を始める前に、2 つの関数を定義しましょう。

最初の関数は appendToTail() です。

function appendToTail(item, array) {
  return [...array, item];
}

const numbers = [1, 2, 3];
appendToTail(10, numbers); // => [1, 2, 3, 10]
ログイン後にコピー

appendToTail() を使用すると、配列の末尾に値を挿入できます。この関数は、[...array, item]という記述方法を使用します。

2 番目の関数は appendToHead() です。

function appendToHead(item, array) {
  return [item, ...array];
}

const numbers = [1, 2, 3];
appendToHead(10, numbers); // => [10, 1, 2, 3]
ログイン後にコピー

appendToHead() は、値が追加された新しい配列を返す純粋な関数です。元の配列の先頭に挿入されます。 [item, ...array] を使用します。

正直に言うと、上記の 2 つの関数のパフォーマンスに基づいて、これらの関数の効率が異なると考える理由はありません。しかし、現実は想像とは異なるかもしれないので、テストを続けてみましょう。

パフォーマンス テスト

MacBook Proを使用して、次の 3 つのブラウザ ラップトップでテストしました[... 配列, 項目][item, ...array]、2 つのパフォーマンスを比較します:

  • Chrome 76
  • Firefox 68
  • Safari 12.1

パフォーマンス テストの結果は次のとおりです:

JavaScriptのスプレッド演算子のパフォーマンスを向上させるにはどうすればよいですか?

予想どおり、Firefox および Safari ブラウザーでは [ ...array, item][item, ...array] のパフォーマンスは同じです。

ただし、Chrome では、[...array, item][item, ...array] の 2 倍の速度で実行されます。これは有益な結果です。

Chrome のスプレッド演算子のパフォーマンスを向上させるには、配列リテラルの先頭にスプレッド演算子を使用します。

const result = [...array, item];
ログイン後にコピー

しかし、別の疑問が生じます。この問題の原因は何ですか?

V8 エンジンのバージョン 7.2 以降、Chrome での JavaScript 実行のサポートが提供され、スプレッド演算子で新しい最適化を実行できるようになりました: 高速パス最適化

これがどのように機能するかを次のような文で説明します。

この最適化を行わないと、エンジンが展開演算子 [...iterable, item],これにより、反復可能オブジェクト iterator.next() の反復子が呼び出されます。反復ごとに、結果配列のメモリが増加し、反復結果が結果配列に追加されます。

しかし、高速パス最適化 は、既知の反復可能オブジェクト (整数配列など) を検出し、反復子オブジェクトの作成を完全にスキップします。次に、エンジンは拡張配列の長さを読み取り、結果の配列にメモリを 1 回だけ割り当てます。次に、配列はインデックスによって伝播され、結果の配列に各項目が追加されます。

高速パスの最適化では、反復オブジェクトの作成がスキップされ、結果にメモリが 1 回だけ割り当てられます。これにより、パフォーマンスが向上します。

サポートされるデータ構造

ファスト パスの最適化は、次の標準 JavaScript データ構造で機能します。

#配列

const numbers = [1, 2, 3, 4];

[...numbers, 5]; // => [1, 2, 3, 4, 5]
ログイン後にコピー

文字列

const message = 'Hi';

[...message, '!']; // => ['H', 'i', '!']
ログイン後にコピー

セット

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] の少なくとも 2 倍の速度で実行されることが示されています。

高速パスは確かに便利ですが、パフォーマンスが重要な場合や大規模な配列を扱う場合には高速パスを使用することをお勧めします。

なぜなら、ほとんどの場合、強制的に最適化を行っても、エンド ユーザーは違いを感じられない可能性が高いからです。

他にも JavaScript での興味深いパフォーマンスの最適化についてご存知ですか? 以下のコメントで教えていただけますか?

この記事があなたに何らかの助けやインスピレーションをもたらすのであれば、いいねやスターをケチらないでください。それが私にとって前に進むための原動力であり、最大の肯定です

元のリンク: https://dmitripavlutin.com/javascript-spread-operator-performance-optimization/

プログラミング関連の知識の詳細については、次を参照してください:

プログラミング ビデオ ! !

以上がJavaScriptのスプレッド演算子のパフォーマンスを向上させるにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:segmentfault.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート