データストアはネットワークアクセスを伴うので、大量のデータを処理しようと思うとネットワークレイテンシーがボトルネックになってきます。そこで今回はデータの追加処理(更新、削除も)高速化するためのアイディアを紹介します。
Promiseとasync/await
JavaScriptに限りませんが、最近のネットワーク処理ではasync/awaitが使われるようになっています。非同期処理が同期処理的に書けて便利な反面、処理が終わらないと次のステップに進めないという問題があります。
例えば100件のデータを追加する処理において、次のような書き方ができます。
Promiseの場合
const promises = []; for (let i = 0; i < 100; i += 1) { const item = new Vertical; promises.push(item .set('name', `${i + 1} items`) .save()); } await Promise.all(promises);
async/awaitの場合
for (let i = 0; i < 100; i += 1) { const item = new Vertical; await item .set('name', `${i + 1} items`) .save(); }
どちらもデータを100件追加する処理なのは変わりませんが、速度では以下のように大幅に違います(単位はms)。
- Promise
3,039 - async/await
18,620
Promiseの方が6倍近く速いという結果になっています。
理由
この速度の違いは、Promise処理の場合はループの時点ですでに次の処理に入っているということです。そして、Promise.allで全処理の完了を待っています。それに対してasync/awaitの場合は一つの保存処理が終わるまでループが進みません。そのため、遅くなります。
課題
Promiseの場合、処理順番は保証されません。そのため、データの並び順はバラバラになります。もし順番を付けたいならば、別途数字のカラムで指定するようにしてください。
まとめ
大量のデータを一気に保存したい場合にはPromiseを使った方が良いでしょう。async/awaitは見やすくて便利ですが、ループ処理ではあまり向いていないようです。ユーザがストレスにならないよう使い分けて実装してください。