LoginSignup
2
1

【アンチパターン】そのGAS遅くない? 処理が遅い場合の改善方法

Last updated at Posted at 2023-12-09

はじめに

GASは手軽にコードを実行でき、Googleアプリケーションとの連携が簡単にできます。
しかし、コードの書き方によっては処理に時間がかかる場合があります。
しかもGASには実行時間制限(6分)があるため、実装方法でミスをすると、処理が完了しないという事態も起こりえます。
この記事では、処理を早くするテクニックを実例を用いて解説します。

APIの呼び出しは最小限に

Apps Script APIをGASから呼び出す際は気を付ける必要があります。
APIの呼び出しには一定の時間がかかり、これが積み重なるとどんどん処理が重くなっていきます。
特に、ループ文の中でAPIを呼び出す事はなるべく避けるようにしてください。

データの取得や作成は一括でする

スプレッドシートなどからデータを取得する際には、なるべく一度にデータを取得しましょう。データの作成時も同様です。
一行一行処理をするといった場合でも、一行ごとにデータを取得するのではなく、一括取得したデータを配列として取り扱い、処理した後に、一括でデータを作成するほうが高速に動作します。

悪い例

以下の例では、forループの中で各行に対してAPIを呼び出しており、データの取り扱いも不適切です。

function badExample() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("シート1");
  var totalRows = sheet.getLastRow();

  for (var i = 1; i <= totalRows; i++) {
    var range = sheet.getRange(i, 1, 1, 3); // Bad:何度もAPIを呼び出している
    var values = range.getValues(); // Bad:個別にデータを取得している

    // ここでvaluesを使って必要な処理を行う

    range.setValues(values); // Bad:個別にデータを作成している
  }
}

良い例

以下の例では、APIの呼び出しやデータの取り扱いが適切になされています。

function goodExample() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("シート1");
  var range = sheet.getDataRange(); // Good:APIの呼び出しを最小限にする
  var data = range.getValues();// Good:一度に全データを取得
  var setData = [] //※2次元配列にしないと反映されない

  for (var i = 0; i < data.length; i++) {
  
    // ここでdata[i]を使ってsetDataに追加する
  
  }

  range.setValues(setData); // Good:変更後のデータを一度にスプレッドシートに反映
}

処理時間計測

それぞれの例の処理時間をスプレッドシートの行データを増やして比較してみました。

実行時間の比較
行数 badExample() goodExample()
10 1,905ms 239ms
100 22,839ms 447ms
1,000 231,814ms 592ms
10,000 実行時間制限オーバー 1,784ms

badExample関数は、行数が10倍になるたびに、実行時間もほぼ10倍になってますね。1,000行を処理するのに、4分弱もかかりました。
それに比べてgoodExample関数は1万行を超えても2秒以内に処理が完了しています。

まとめ

意外とやってしまいがちなアンチパターンの改善点をまとめました。良きGASライフを!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1