ニフクラ mobile backend(mBaaS)お役立ちブログ

スマホアプリ開発にニフクラ mobile backend(mBaaS)。アプリ開発に役立つ情報をおとどけ!

データストアを高速化する(データ追加編)

f:id:mbaasdevrel:20180913163950p:plain

データストアはネットワークアクセスを伴うので、大量のデータを処理しようと思うとネットワークレイテンシーがボトルネックになってきます。そこで今回はデータの追加処理(更新、削除も)高速化するためのアイディアを紹介します。

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は見やすくて便利ですが、ループ処理ではあまり向いていないようです。ユーザがストレスにならないよう使い分けて実装してください。

中津川 篤司

中津川 篤司

NCMBエヴァンジェリスト。プログラマ、エンジニアとしていくつかの企業で働き、28歳のときに独立。 2004年、まだ情報が少なかったオープンソースソフトの技術ブログ「MOONGIFT」を開設し、毎日情報を発信している。2013年に法人化、ビジネスとエンジニアを結ぶDXエージェンシー「DevRel」活動をスタート。