2014年10月29日水曜日

Google Apps Scriptの処理速度検証

~はじめに~

 はじめまして。A-AUTO 50開発チームの井下と申します。

 A-AUTO50以外にも様々な技術の研究を行っており、
 ブログにはGoogle Apps Scriptを主な題材として投稿させていただきます。

 Google Apps Script自体については、こちらをご参照ください。




~Google Apps Scriptの課題~

 Google Apps ScriptはGoogleのサービスとの連携が容易であることや、
 ほぼJavaScriptの感覚で書けるために学習コストが低い利点がありますが、
 実際に利用していると、いくつか課題を感じると思います。

 特によく言われるのは「処理の速度」で、
 個人的にも処理の体感速度は決して早くはありません…。

 また、実行するメソッドの処理に一定時間(2014/10時点で360秒)以上かかっている場合、
 途中で処理が中断されてしまうため、速度を求めていないからと放置していると痛い目に遭います。
 (※井下は処理速度をまるで考慮せず、処理対象が膨大なコードを書いた際に何度か遭いました…)

 ただ少しでも処理速度を向上するために、様々なノウハウが見られるようになっていますね。
 
 スプレッドシートのデータ貼り付けは「setValue」で1つ1つのデータを貼り付けるのではなく、
 「setValues」で指定した範囲に一括で貼り付ける、というものが代表的な例でしょうか。

 上記のノウハウはGoogle Apps Script以外にも言えると思いますが、
 実際どの程度差が出るものなのでしょうか?
 今回は処理速度を検証し、具体的なノウハウの効果を目に見えるようにしてみます。


~処理速度検証方法~

 検証方法は非常にシンプルに、n×nの範囲に値をセットさせ、
 その処理に何秒かかったかを実行トランスクリプトから確認します。
 セットさせる値は行数×列数とします。(下の図のように九九の表が作成されるイメージです)
 

 n×nの範囲に値をセットさせるロジックは以下の2つです。
 ①setValueでセル1つに値をセットする処理をn×n回ループさせる
 ②setValuesでn×nの範囲に一括で値をセットする(セットする値はセット前に生成する)

 実際のコードはこのようなものを用意しました。
 ①setValue利用
  for(var row = 1; row <= MAX_ROW; row++){
    for(var column = 1; column <= MAX_COLUMN; column++){
      sheet.getRange(row, column).setValue(row * column);
  }

 ②setValues利用
  var values = getValues(); //セットする値の生成
   sheet.getRange(1, 1, MAX_ROW, MAX_COLUMN).setValues(values);

 10×10、50×50、100×100、500×500をそれぞれ3回ずつ計測し、
 その平均値で差をどれくらい出るか検証してみます。


~処理速度検証結果~
 

10×10 50×50 100×100 500×500
①setValue利用 0.142秒 1.778秒 7.361秒 197.452秒
②setValues利用 0.088秒 0.215秒 0.634秒 36.676秒
①と②の差 0.054秒 1.563秒 6.727秒 160.776秒

 結果は上記の表のようになりました。
 セット対象のセルが増えれば増えるほど、差が顕著になっていることが分かります。
 500×500(25,000セルの値のセット)になると、160秒の差が発生しています。

 前述したように、一定時間を超えるとGoogle Apps Scriptの処理は中断されてしまうので、
 日々増大するデータを管理している場合はsetValuesを使うようにしたほうが良いですね。
 
 また、上記データを元に1セルあたりにかかっている時間を算出してみました。
 (②はセットする値の生成があるので、セルへのセット以外にも
  時間がかかる要素はありますが、今回はそこを気にしないことにしています)

10×10 50×50 100×100 500×500
①setValue利用 0.001423秒 0.000711秒 0.000736秒 0.000790秒
②setValues利用 0.000883秒 0.000086秒 0.000036秒 0.000147秒

 ①setValue利用は10×10以外はあまり処理速度に変化がありません。
 ②setValues利用は100×100がもっとも速く、500×500がもっとも遅くなっています。

 事前にどれだけのデータ量までであれば処理可能であるか、
 キャパシティを意識してスクリプトを組んでいけば、後で痛い目にあわずに済みますね。

~今後~

 今後も基本的にGoogle Apps Scriptについて気になったことや、
 検証してみたこと、調査してみたことを取り扱って行こうと考えています。

 次回は11/7を予定しています。

0 件のコメント:

コメントを投稿