【GAS】スクリプトが遅い時の高速化テクニック|getValues・setValuesとmap活用で61秒→1秒未満に
GASのスクリプトを組んで自動化したものの「実行が遅い」「6分制限や30分制限で途中終了してしまう」という問題に悩んでいませんか?
本記事では、GASが遅くなる最大の原因である「スプレッドシートへの読み書き回数」を削減する高速化テクニックを解説します。同じ処理が約61秒から1秒未満に改善した実例をコード付きで紹介します。
目次
GASが遅くなる最大の原因:getValue/setValueのループ内呼び出し
スプレッドシートの値を取得するgetValue()・getValues()、値を書き込むsetValue()・setValues()は処理に時間がかかります。
1〜2回なら問題ありませんが、数百回とループ内で呼び出すと大きなボトルネックになります。
遅いコードの例(約61秒)
消費税を計算してスプレッドシートに書き出す処理を例に説明します。

// NG例:forループ内にgetValue/setValueが入っている(200行で約61秒)
function tax1(){
const ROW = 200
const ss = SpreadsheetApp.getActiveSpreadsheet()
const sh = ss.getSheetByName("TAX")
const TAX = sh.getRange("B2").getValue()
let price, tax_price
for(i = 5; i <= ROW + 4; i++){
price = sh.getRange(i, 2).getValue() // 毎回スプレッドシートにアクセス
tax_price = price * (1 + TAX)
sh.getRange(i, 3).setValue(tax_price) // 毎回スプレッドシートに書き込み
}
}
200行のデータに対して400回(読み200回+書き200回)のスプレッドシートアクセスが発生するため非常に遅くなります。
高速化テクニック1:getValues/setValuesで一括処理する(1秒未満)
getValue/setValueをループの外に出し、配列で一括読み書きします。
// OK例:一括取得・一括書き込みで高速化(200行で1秒未満)
function tax2(){
const ROW = 200
const ss = SpreadsheetApp.getActiveSpreadsheet()
const sh = ss.getSheetByName("TAX")
const TAX = sh.getRange("B2").getValue()
// 一括取得(スプレッドシートアクセス1回)
let price_list = sh.getRange(5, 2, ROW, 1).getValues()
let tax_price = []
for(i = 0; i < ROW; i++){
tax_price[i] = []
tax_price[i][0] = price_list[i][0] * (1 + TAX) // メモリ内で計算
}
// 一括書き込み(スプレッドシートアクセス1回)
sh.getRange(5, 3, price_list.length, 1).setValues(tax_price)
}
スプレッドシートへのアクセスが合計2回(読み1回+書き1回)になるため劇的に高速化されます。
高速化テクニック2:forループをmapに置き換える(さらに高速化)
forループをmap()に置き換えることで、さらにコードをシンプルかつ高速にできます。
// ベスト例:mapを使ってシンプルに高速化
function tax3(){
const ROW = 200
const ss = SpreadsheetApp.getActiveSpreadsheet()
const sh = ss.getSheetByName("TAX")
const TAX = sh.getRange("B2").getValue()
let price_list = sh.getRange(5, 2, ROW, 1).getValues()
// mapで配列を変換(1行で書ける)
let tax_price = price_list.map(elm => [elm[0] * (1 + TAX)])
sh.getRange(5, 3, price_list.length, 1).setValues(tax_price)
}
パフォーマンス比較
- tax1(forループ内でgetValue/setValue):約61秒
- tax2(getValues/setValues一括処理):1秒未満
- tax3(mapを使用):1秒未満
高速化のポイントまとめ
- getValue/setValueはループ外に出す:ループ内で呼ぶ回数を最小限に
- getValues/setValuesで一括処理:配列として一度に読み書きする
- mapやfilterを活用:配列操作はforよりmap/filterが高速で可読性も高い
- スプレッドシートアクセスは最小限に:一度取得したデータはメモリ上で処理する







ディスカッション
コメント一覧
まだ、コメントがありません