目的
- こんな記事を書いた
- で。たくさん書き方あるが、結局どれがいいのか?
- そうだ、パフォーマンス測定しよう
tl:dr;
- 「可読性 > 実行速度」なら、「for-of」または「while」
- 「可読性 <<<<< 実行速度」なら、「async/await なしの reduce」
計測環境
- OS: Windows 7
- CPU: Core i5 2500K (1.6 GHz でクロック固定)
- Node: v12.2.0
- TypeScript: 3.4.5
- benchmark: 2.1.4
src
計測結果
トランスパイル後のファイルサイズ
es5 | es2016 | es2017 | |
---|---|---|---|
sequentialForOf.js | 3446 | 1030 | 381 |
sequentialReduce.js | 4000 | 1300 | 611 |
sequentialReduceNoAsync.js | 1038 | 988 | 988 |
sequentialWhile.js | 3401 | 1103 | 454 |
単位は byte
es2016以下の場合
- async/await を使用した場合、トランスパイルで polyfill が挿入される
- よって、 async/await を使用しなければ、polyfill 分のサイズを削減できる
- ただし、その他の実装でも一切 async/await 使ってない場合に限る
- src全体で見て、他の実装で async/await を使っている場合、その実装のために polyfill が挿入される
- そのため、直列実行の実装を工夫しても polyfill 分のサイズは必ず増える
es2017以上の場合
- いずれの実装も、polyfillは挿入されない
- よって、書いたコード分のファイルサイズになる
所感
- まぁ、妥当な結果
ベンチマーク
- 各 target の出力結果の JavaScript を実行
- 1 スレッド、100 Promise の直列処理 * 5 回計測の平均
- es5 だけ 1 回異常値が出たため除外、 4 回計測の平均としている
- 「Relative」列は、最速を 100 % とした相対値
target: es5
Case name | Average (ops/sec) | Relative |
---|---|---|
sequentialReduce | 181328.5 | 35.62% |
sequentialReduceNoAsync | 509098.0 | 100.00% |
sequentialForOf | 316693.8 | 62.21% |
sequentialWhile | 303165.3 | 59.55% |
target: es2016
Case name | Average (ops/sec) | Relative |
---|---|---|
sequentialReduce | 124173.6 | 26.35% |
sequentialReduceNoAsync | 471195.6 | 100.00% |
sequentialForOf | 120810.6 | 25.64% |
sequentialWhile | 119936.8 | 25.45% |
target: es2017
Case name | Average (ops/sec) | Relative |
---|---|---|
sequentialReduce | 387086.8 | 75.98% |
sequentialReduceNoAsync | 509441.2 | 100.00% |
sequentialForOf | 466661.2 | 91.60% |
sequentialWhile | 446598.4 | 87.66% |
所感
- こうして見ると「reduce + async/await なし」のパターンが最速
- 「promise sequential」でググってよく出る reduce 使ったサンプルコードは、一応理にかなってたらしい
まとめ
- 測定しておいてアレだが、ぶっちゃけ「非同期処理を直列に実行したいけど、プログラムの処理時間(マイクロ秒・ナノ秒単位)は切り詰めたい」なんて需要が思い付かない・・・
- なので、可読性の高い(※主観)「for-of」または「while」で実装すればよいのではないか
- ループの途中で break したいケースでは、確実に「for-of」または「while」の方が実装しやすい
- もしパフォーマンスチューニングする場合は、async/await を捨て糞コードへ先祖返りする前に、見直すべき部分があるはず