「forEachは可読性高いけど性能は低い」みたいな印象を持っていたのですが、測定してみたらそんなことありませんでした、っていうタイトル通りのお話です。
測定結果
5回ほど測定してみましたが、forEachが1.7倍ほど高速という結果になりました。
for…of文 | forEach文 | |
---|---|---|
1回目 | 33.4 | 15.7 |
2回目 | 22.0 | 15.5 |
3回目 | 24.0 | 14.7 |
4回目 | 24.5 | 14.3 |
5回目 | 21.9 | 14.6 |
平均 | 25.2 | 15.0 |
測定に使用したコード
const COUNT_MAX = 1000000;
console.log('elapsedTime1[ms],elapsedTime2[ms]');
for(let i = 0; i < 5; i++) {
measurement();
}
function measurement() {
let myMap = new Map();
for(let i = 0; i < COUNT_MAX; i++) {
let num = String(i).padStart(8, '0');
myMap.set('key' + num, 'val' + num);
}
// 同じオブジェクト使うと最適化されて後が速くなるとかありそうなので別オブジェクトで定義しておく
let myMap2 = new Map();
for(let i = 0; i < COUNT_MAX; i++) {
let num = String(i).padStart(8, '0');
myMap2.set('key' + num, 'val' + num);
}
// forEach文
const startTime1 = performance.now();
myMap.forEach((value, key) => {
// 参照しない場合は最適化されて参照時と性能が全然違うとかありそうなので念の為参照だけしておく
if (key == value) {
// 特に意味のない処理(デッドルート)
console.log(`key=${key}, value=${value}`);
}
});
const elapsedTime1 = performance.now() - startTime1;
// for...of文
const startTime2 = performance.now();
for (const [key, value] of myMap2.entries()) {
// 参照しない場合は最適化されて参照時と性能が全然違うとかありそうなので念の為参照だけしておく
if (key == value) {
// 特に意味のない処理(デッドルート)
console.log(`key=${key}, value=${value}`);
}
}
const elapsedTime2 = performance.now() - startTime2;
console.log(`${elapsedTime1},${elapsedTime2}`)
}
参考
繰り返し処理について
https://qiita.com/think49/items/0c5ea1c9e2545fa2eed2
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Loops_and_iteration
https://stackoverflow.com/questions/49809601/best-practice-javascript-for-loop
性能測定について
https://sbfl.net/blog/2017/12/01/javascript-measure-time/
コメント