forとforEachのパフォーマンスの違いや、配列に値を入れてメモリを確保した状態と、そうでない場合のパフォーマンスの違いを検証してみようと思い、以下のようなコードを書いて実行してみました。
しかし、結果は誤差レベルであったり、むしろ、forEachの方がforよりも早い場合が実行する時によっては、あったりなかったりでした。
for文が最速ではなかったのですか?
僕の検証方法がおかしいのでしょうか?それとも、こういうものですか?
ターミナルのnode.js環境で実行しました。
パターン1
配列に値を入れてメモリ確保 & for文内で配列参照せずにログ出力
'use strict'; var numbers = Array.from({length: 1000000}, (v, k) => k); var max = numbers.length; console.time('パターン1'); for (let i = 0; i < max; i++) { console.log(i); } console.timeEnd('パターン1'); パターン1: 32641.203ms
パターン2
配列に値を入れてメモリ確保 & for文内で配列参照して配列内の値をログ出力
'use strict'; var numbers = Array.from({length: 1000000}, (v, k) => k); var max = numbers.length; console.time('パターン2'); for (let i = 0; i < max; i++) { console.log(numbers[i]); } console.timeEnd('パターン2'); パターン2': 32736.931ms
パターン3
配列に値を入れてメモリ確保 & forEachで配列内の値をログ出力
'use strict'; var numbers = Array.from({length: 1000000}, (v, k) => k); var max = numbers.length; console.time('パターン3'); numbers.forEach((v) => console.log(v)); console.timeEnd('パターン3'); パターン3': 32587.072ms
パターン4
配列使わない & for文内でログ出力
'use strict'; var max = 1000000; console.time('パターン4'); for (let i = 0; i < max; i++) { console.log(i); } console.timeEnd('パターン4'); パターン4: 32935.210ms
★再トライ
miyabi-sunさんからの回答を参考に再トライしてみました。
※ console.logはそのままで再トライしてしまいました。
結果的に実行する度にどれが早いか遅いかが誤差レベルで変わってしまうので、for文がforEachより早いというのは分かりませんでした。
パターン1
配列に値を入れてメモリ確保 & for文内で配列参照せずにログ出力
'use strict'; var numbers = Array.from({length: 1000000}, (v, k) => k); var max = numbers.length; console.time('パターン1'); for (let i = 0; i < max; i = (i+1)|0) { console.log(i); } console.timeEnd('パターン1'); //パターン1: 32958.586ms
パターン2
配列に値を入れてメモリ確保 & for文内で配列参照して配列内の値をログ出力
'use strict'; var numbers = Array.from({length: 1000000}, (v, k) => k); var max = numbers.length; console.time('パターン2'); for (let i = 0; i < max; i = (i+1)|0) { console.log(numbers[i]); } console.timeEnd('パターン2'); //パターン2': 32869.883ms
パターン3
配列に値を入れてメモリ確保 & forEachで配列内の値をログ出力
'use strict'; var numbers = Array.from({length: 1000000}, (v, k) => k); var max = numbers.length; console.time('パターン3'); numbers.forEach((v) => console.log(v)); console.timeEnd('パターン3'); //パターン3': 32855.013ms
パターン4
配列使わない & for文内でログ出力
'use strict'; var max = 1000000; console.time('パターン4'); for (var i = 0; i < max; i = (i+1)|0) { console.log(i); } console.timeEnd('パターン4'); //パターン4: 32951.688ms
★再々トライ
最後に、miyabi-sunの指摘通り、console.logをprocess.stdout.writeに変えて実行してみました。
また、今回はforEachに渡す関数を匿名関数ではなく、事前に変数に代入してforEachに渡し実行するパターン5を追加しました。
パターン1
配列に値を入れてメモリ確保 & for文内で配列参照せずにログ出力
'use strict'; var numbers = Array.from({length: 1000000}, (v, k) => k); var max = numbers.length; console.time('パターン1'); for (let i = 0; i < max; i = (i+1)|0) { process.stdout.write(`${i}\n`); } console.timeEnd('パターン1'); //パターン1: 32088.090ms
パターン2
配列に値を入れてメモリ確保 & for文内で配列参照して配列内の値をログ出力
'use strict'; var numbers = Array.from({length: 1000000}, (v, k) => k); var max = numbers.length; console.time('パターン2'); for (let i = 0; i < max; i = (i+1)|0) { process.stdout.write(`${numbers[i]}\n`); } console.timeEnd('パターン2'); //パターン2': 32415.275ms
パターン3
配列に値を入れてメモリ確保 & forEachで配列内の値をログ出力
'use strict'; var numbers = Array.from({length: 1000000}, (v, k) => k); var max = numbers.length; console.time('パターン3'); numbers.forEach((v) => process.stdout.write(`${v}\n`)); console.timeEnd('パターン3'); //パターン3': 31955.411ms
パターン4
配列使わない & for文内でログ出力
'use strict'; var max = 1000000; console.time('パターン4'); for (var i = 0; i < max; i = (i+1)|0) { process.stdout.write(`${i}\n`); } console.timeEnd('パターン4'); //パターン4: 32404.780ms
パターン5
配列に値を入れてメモリ確保 & forEachで配列内の値をログ出力(事前に関数を変数に代入してforEachに渡す)
'use strict'; var numbers = Array.from({length: 1000000}, (v, k) => k); var max = numbers.length; console.time('パターン5'); const log = (v) => process.stdout.write(`${v}\n`); numbers.forEach(log); console.timeEnd('パターン5'); //パターン5': 32368.805ms
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。