先日、GAS でいつものようにコードを組んでいたのですが、どうも処理が追いつかずサーバ側のタイムアウトが発生する事案に遭遇。
以下の記事にもあるように、GAS は API をコールしまくると途端に処理速度が低下するのはよくある話で、今回のコードも何の考えもなしにループの終了条件で getLastRow()を設定していた。
[GAS][スプレッドシート]処理速> 度を向上するには: 逆引き Google Apps Script
いつもならバグ見つかってよかったー、で終わってしまうのですがちょっと気になることがあったので検証してみました。
【検証】 GAS の処理が遅いって言われてるけど、実際どうなの?
ということで今回はよくやりそうな処理のサンプルを作ってみたので実測値を見てみる。
[検証 1]for 文に getLastRow()を突っ込んだ場合の処理遅延
以下のコードを実行してみる。
function speedCheck1() {
var ss = SpreadsheetApp.openById(SS_KEY).getActiveSheet();
var counter = ss.getLastRow();
Logger.log('speed check start:getLastRow()');
for(var i = 0;i < ss.getLastRow();i++){}
Logger.log('speed check end:getLastRow()->count:'+i);
Logger.log('speed check start:counter');
for(var i = 0;i < counter;i++){}
Logger.log('speed check end:counter->count:'+i);
}
結果は以下。
[13-10-24 00:31:46:496 JST] speed check start:getLastRow()
[13-10-24 00:31:54:044 JST] speed check end:getLastRow()->count:100
[13-10-24 00:31:54:045 JST] speed check start:counter
[13-10-24 00:31:54:045 JST] speed check end:counter->count:100
[検証 2]ループ内でスプレッドシートの値を getValue()しちゃった場合の処理遅延
次はこちらのコード。
function speedCheck2() {
var ss = SpreadsheetApp.openById(SS_KEY).getActiveSheet();
var array = ss.getDataRange().getValues();
var counter = ss.getLastRow();
var result = new Array();
Logger.log('speed check start:getValue()');
for(var i = 0;i < counter;i++){
result[i] = ss.getRange(i+1,1).getValue();
}
Logger.log('speed check end:getValue()->count:'+i);
Logger.log('speed check start:assignment');
for(var i = 0;i < counter;i++){
result[i] = array[i][0];
}
Logger.log('speed check end:assignment->count:'+i);
}
結果
結果はご覧の通り。
[13-10-24 00:36:15:285 JST] speed check start:getLastRow()
[13-10-24 00:36:22:977 JST] speed check end:getLastRow()->count:100
[13-10-24 00:36:22:977 JST] speed check start:counter
[13-10-24 00:36:22:978 JST] speed check end:counter->count:100
整理すると
[検証 1] 7452ms
[検証 2] 7692ms
という結果でした。メソッドによって 1call 当たりの処理速度は当然ながら変わってくると思いますので参考程度に
見てもらえればと思います。
しかしながら 100 回 call しただけで 7 秒以上の差が出ているのは驚きなので、複雑な処理になっている時ほど処理を改善すると効果絶大です。
処理速度にお悩みでしたらコード内にこういった処理が潜んでいるかもしれません。