意外と知らないJSのループ速度テストのいろいろを徹底解説

意外と知らないJSのループ速度テストのいろいろを徹底解説

序文

ループ速度をテストする前に、100 万個のデータを含む配列を作成しましょう。

定数len = 100 * 10000;
定数arr = [];
(i = 0; i < len; i++) の場合 {
  arr.push(Math.floor(Math.random() * len));
}

テスト環境は次のとおりです。

1. コンピューター:iMac (10.13.6)

2. プロセッサ: 4.2GHz Intel Core i7;

3. ブラウザ: Chrome (89.0.4389.82)

1. forループ

for ループは最もよく使われるループ方法です。その最大の利点は、構造が明確でいつでも停止できることです。

まずは10回テストしてみましょう:

console.log('テスト');
(k = 0; k < 10; k++とします) {
  コンソールで時間を指定します。
  合計を 0 とします。
  (i = 0; i < len; i++) の場合 {
    合計 += arr[i] % 100;
  }
  コンソールのtimeEnd('for');
}

最終結果は次のとおりです。

1回目と2回目は時間がかかりましたが、3回目以降は1.25ms程度で安定しました。

2. whileループとdo-whileループ

これら 2 つを組み合わせると、構造が十分に類似しており、いつでも破損して停止することもできます。

console.log('\nテスト中');
(k = 0; k < 10; k++とします) {
  コンソールで時間('while');
  合計を 0 とします。
  i = 0 とします。
  (i < 長さ) の間 {
    合計 += arr[i] % 100;
    私は++;
  }
  コンソールのtimeEnd('while');
}
console.log('\ntest do-while');
(k = 0; k < 10; k++とします) {
  console.time('do-while');
  合計を 0 とします。
  i = 0 とします。
  する {
    合計 += arr[i] % 100;
    私は++;
  } ながら (i < len);
  console.timeEnd('do-while');
}

while ループと do-while ループの結果はほぼ同じです。ブラウザーで実行されている while ループの結果を見てみましょう。

for ループと同じくらいの速さです。

3. forEach、map、reduce ループ

次に、よく使用される 3 つの配列メソッド (forEach、map、reduce など) について説明します。これら 3 つのメソッドは、ES6 標準に追加された新しい構文です。

3.1 forEachの簡単な紹介

これらのメソッドはループを停止できません。break または return のどちらを使用しても、ループ全体を停止することはできません。例えば、3の倍数に遭遇したらループを停止したいというテストを行うことができます。

[1, 2, 3, 4, 5].forEach((項目) => {
  console.log(`before return: ${item}`);
  if (item % 3 === 0) {
    戻る;
  }
  console.log(`戻り後: ${item}`);
});

結果は次のとおりです。

実行結果から、return はループに続くステートメントを実行せず、ループ全体を停止しないことがわかります。次の 4 と 5 は正常に出力されます。

玄麦のようにサイクルを止めることはできないというのは本当ですか?いいえ、このサイクルを止める別の方法があります。例外がスローされます:

試す {
  [1, 2, 3, 4, 5].forEach((項目) => {
    console.log(`before return: ${item}`);
    if (item % 3 === 0) {
      新しいエラーをスローします('break forEach');
    }
    console.log(`戻り後: ${item}`);
  });
} キャッチ (e) {}

forEach で例外がスローされた後、ループを停止し、try-catch を使用して例外をキャッチして、サービス全体が中断されるのを防ぐことができます。

forEach ループを停止することも可能ですが、実装するのはかなり面倒です。したがって、ループ全体を停止する必要がない場合は、forEach や map などのループ メソッドを使用できます。それ以外の場合は、他のループ メソッドを使用する必要があります。

3.2 forEach等の速度テスト

さて、次に、これら 3 つのサイクル方法のサイクル速度をテストします。

// forEach のテスト:
console.log('\ntest forEach');
(k = 0; k < 10; k++とします) {
  コンソールで時間を設定します。
  合計を 0 とします。
  arr.forEach((アイテム) => {
    合計 += 項目 % 100;
  });
  コンソールのtimeEnd('forEach');
}
// マップテスト:
console.log('\nテストマップ');
(k = 0; k < 10; k++とします) {
  コンソールに時間を表示します。
  合計を 0 とします。
  arr.map((アイテム) => {
    合計 += 項目 % 100;
  });
  コンソールのtimeEnd('マップ');
}
// 削減のテスト:
console.log('\nテスト削減');
(k = 0; k < 10; k++とします) {
  コンソールで時間を減らす
  合計を 0 とします。
  arr.reduce((_, 項目) => {
    合計 += 項目 % 100;
  }, 0);
  コンソールのtimeEnd('reduce');
}

これら 3 つのループの時間はほぼ同じなので、ここでは forEach のテスト結果のみをインターセプトしました。

10 回のループを実行した後、forEach の実行時間は約 10.8 ミリ秒となり、これは上記の for ループと while ループのほぼ 10 倍の長さになります。

4. ~の

ES6 は C++、Java、C#、Python から借用し、すべてのデータ構造を走査するための統一された方法として for...of ループを導入します。

4.1 for-ofの簡単な紹介

データ構造に Symbol.iterator プロパティが展開されている限り、そのデータ構造には iterator インターフェイスがあると見なされ、そのメンバーは for...of ループを使用して走査できます。つまり、for...of ループはデータ構造の Symbol.iterator メソッドを呼び出します。

for...of ループのスコープには、配列、Set および Map 構造、一部の配列のようなオブジェクト (引数オブジェクト、DOM NodeList オブジェクトなど)、後述する Generator オブジェクト、および文字列が含まれます。

for-of は値自体を取得しますが、for-in はキーを取得し、キーを通じて現在のデータを取得します。

const フルーツ = ['リンゴ', 'バナナ', 'オレンジ', 'レモン'];

for (果物の定数値) {
  console.log(値); // 'リンゴ'、'バナナ'、'オレンジ'、'レモン'
}

4.2 for-ofループの速度測定

for-of ループの速度をテストするコード:

console.log('\ntest for-of');
(k = 0; k < 10; k++とします) {
  console.time('for-of');
  合計を 0 とします。
  for (arrのconst値) {
    合計 += 値 % 100;
  }
  console.timeEnd('for-of');
}

テスト結果:

同じループを複数回繰り返す場合、最初の 2 つの for-of ループには 15 ミリ秒を超える時間がかかります。しかし、その後の実行では、ループ速度は約 1.5 ミリ秒に低下し、これは for ループ時間とほぼ同じになります。

5. for-in ループ

for-in は通常、オブジェクト型のループに使用されますが、配列のループにも使用できます。結局のところ、すべてのデータ型の祖先はオブジェクト型です。

console.log('\nテストfor-in');
(k = 0; k < 10; k++とします) {
  console.time('for-in');
  合計を 0 とします。
  for (let key in arr) {
    合計 += arr[キー] % 100;
  }
  console.timeEnd('for-in');
}

テスト結果:

for-in ループの速度テスト データは驚くべきもので、まさに別格であり、最良の場合、少なくとも 136 ミリ秒かかります。 for-in ループの効率が非常に低いことがわかります。

配列型データには for-in ループを使用しないでください。Object 型データの場合は、まず Object.values() を介してすべての値データを取得し、次に forEach ループを使用します。

定数obj = {};
(i = 0; i < len; i++) の場合 {
  obj[i] = Math.floor(Math.random() * len);
}
(k = 0; k < 10; k++とします) {
  console.time('forEach-values');
  合計を 0 とします。
  Object.values(obj).forEach((item) => {
    合計 += 項目 % 100;
  });
  console.timeEnd('forEach-values');
}

さらに 1 ステップ追加しても、ループ時間は約 14 ミリ秒となり、for-in よりもはるかに高速になります。

6. 結論

すべてのループ データを比較してみましょう。ここでは、各ループのテスト数を 100 に調整します。横軸はループ数、数値軸はループ時間です。

1. for ループ、while ループ、d-while ループは最も時間がかかりません。

2. for-of ループは少し時間がかかります。

3. forEach ループ、map ループ、reduce ループのデータは似ていますが、for-of ループの継続時間はわずかに長くなります。

4. for-in ループは最も時間がかかります。

各ループの期間は異なります。ループ方法を選択するときは、時間を考慮するだけでなく、セマンティクスと使用シナリオも考慮する必要があります。

以上、意外と知らないJSの各種ループ速度測定について詳しく説明しました。JSの各種ループ速度測定についてさらに詳しく知りたい方は、123WORDPRESS.COM内の他の関連記事もぜひご注目ください!

以下もご興味があるかもしれません:
  • JavaScript ループトラバーサルの 24 種類のメソッドをすべてご存知ですか?
  • JavaScriptのループの違いについての詳細な説明
  • JavaScript イベント ループのケース スタディ
  • JavaScript における 3 つの for ループ ステートメントの使用の概要 (for、for...in、for...of)
  • jsのイベントループ機構の解析
  • JS の配列トラバーサルについて、一般的なループをいくつ知っていますか?
  • JavaScript で円形カルーセルを実装する
  • JavaScript の例におけるループの使用法の詳細な説明

<<:  TomcatはXMLを解析し、リフレクションを通じてオブジェクトを作成します。

>>:  mysql.data.dll ドライバーのさまざまなバージョンの簡単な分析

推薦する

LinuxでTomcatのポート番号を変更する方法

ここには複数の Tomcat があります。それらを同時に使用する場合は、ポート番号を別の番号に変更す...

面接でよく聞かれる Vue 修飾子 13 個

目次1. 怠惰な2.トリム3.番号4.停止5. キャプチャ6.自分7.一度8.予防する9.ネイティブ...

HTTPS の原則の説明

HTTPS ウェブサイトの構築コストが下がるにつれて、ほとんどのウェブサイトが HTTPS プロトコ...

VMware Workstation 14 Pro は CentOS 7.0 をインストールします

VMware Workstation 14 ProにCentOS 7.0をインストールする具体的な方...

TCPソケットSYNキューとAcceptキューの差異分析

まず、「LISTENING」状態の TCP ソケットには 2 つの独立したキューがあることを理解する...

Linuxカーネルスケジューラソースコード初期化の分析

目次1. はじめに2. スケジューラの基本概念2.1. 実行キュー (rq) 2.2 スケジューリン...

mysql 行列変換サンプルコード

1. 需要3 つのテーブルがあります。一定期間にわたるさまざまな抗生物質感受性の結果、つまり rep...

暗号化における https の Apache 展開の概要

目次目的実験環境実験原理実験手順1. 独立したCAを生成する2. サーバーの秘密鍵と署名要求ファイル...

冗長カーネルを削除するLinuxディープインの実装方法

前の記事では、deepin linux に新しいカーネルを手動でインストールする方法について説明しま...

時系列転位修復ケースを実装するSQL

目次1. 要件の説明2. アイデアの概要1. 延長を要求する2. アイデアの概要3. SQLコード1...

HTML にネストされた div の無効なマージンに対する解決策

div がネストされているときに margin が機能しない問題の解決策を次に示します。さて、マージ...

Unicode 署名 BOM の詳細な説明

Unicode 署名 BOM - BOM とは何ですか? BOM は Byte Order Mark...

HTML の空リンク href="#" と href="javascript:void(0)" の違い

# には位置情報が含まれます。デフォルトのアンカーは #top で、これは Web ページの上部です...

MySQL データベース内の同じテーブルを同時にクエリして更新する方法

通常のプロジェクトでは、1 回の入札で同時にデータを更新および照会する必要があるという問題によく遭遇...

Ubuntu 基本チュートリアル: apt-get コマンド

序文apt-get コマンドは、Ubuntu システムのパッケージ管理ツールです。パッケージのインス...