狠狠撸
Submit Search
パフォーマンスの良いGASの書き方 Best Practice
?
Download as PPTX, PDF
?
20 likes
?
16,334 views
啓介 大橋
Follow
Atmosphere Tokyo 2014 Sandbox Session. gcp ja night × TokyoGAS Day2 GAS Session.
Read less
Read more
1 of 70
Download now
Downloaded 35 times
More Related Content
パフォーマンスの良いGASの書き方 Best Practice
3.
しょっちゅう 「XXXってサイトにある、 このサンプルコードを コピーして使ってるのだけど、 うちの会社のデータ件数だと タイムアウトしちゃうんです。 どうにか助けて下さい」 って言われて、毎回同じ内容で返答していて、 流石に疲れてきたので ちゃんとパフォーマンスの話をするからお前ら聞 いてろ下さい
6.
何やってる?
8.
@soundTricker318 http://goo.gl/ZpUOs
9.
http://www.bfts.co.jp
11.
Contents うそ… 私のスクリプト 遅すぎ? パフォーマンス の良い書き方 まとめ Start End
12.
う そ ? ? ? 私 の ス ク リ プ ト 遅 す ぎ ? ? ? ? http://www.pakutaso.com/
13.
公式ドキュメントにも 有りますが…
14.
? GASは書き方によって非常にパフォーマンスが変 わります。 うそ…私の…
15.
质问
16.
GASを使ったことがある人? 质问
17.
GASでサンプルコードを コピーして 使ったことがある人? 质问
18.
GASでサンプルコードを コピーして 社内のシステムとして 使っている人? 质问
19.
GASでサンプルコードを コピーして 社内のシステムとして 使ってタイムアウトした人? 质问
20.
? 巷のサンプルコードは比較的パフォーマンスが 悪いコードを書いている – 公式ドキュメントに書いてある書き方を守ってな いことが多い ?
https://developers.google.com/apps- script/best_practices?hl=ja – 多分読みやすくするためにそうしているのだと思い ます。 サンプルコード…
21.
? パフォーマンスが悪いコードを使うと… –処理が終わらなくてタイムアウトする –なんかGASで作るの嫌になる –GAS遅い…と言いふらすようになる –困る サンプルコード
22.
パ フ ォ ー マ ン ス の 良 いス ク リ プ ト で い い 感 じ に http://www.pakutaso.com/
23.
パフォーマンスの良い スクリプトの書き方
27.
? Spreadsheetに色つける処理 –データは100×100セル –セルに「hoge」と書いてあったら黄色に –ないなら無職 今回の処理
28.
以下のコードをSpreadsheet上のGASで実行すれば作れます。 今回の処理 var arr =
["hoge", "fuga", "foo", "bar" , "bus", "あいうえお", "かきくけこ"]; function make() { var grid = []; var header = []; for (var c = 0; c < 100; c++) { header.push(c + 1); } grid.push(header); for (var r = 1; r < 101; r++) { var row = []; for (var c = 0; c < 100; c++) { row.push(arr[Math.floor(Math.random() * arr.length)]); } grid.push(row); } SpreadsheetApp.getActiveSheet().getRange(1, 1, 101, 100).clear().setValues(grid); }
30.
function badCode() { var
spreadsheet = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqS ZrCHMCRL-LEEqQK2n4yQO-o/edit#gid=0"); for(var row = 2; row <= 101; row++) { for(var col = 1; col <= 100; col++) { var value = spreadsheet.getSheetByName("シート1").getRange(row, col).getValue(); if (value == "hoge") { spreadsheet.getSheetByName("シート1").getRange(row, col).setBackground("yellow"); } } } } 悪いコード
32.
function goodCode() { var
spreadsheet = SpreadsheetApp.openById("1kzi8pXTZZrABgTGbJFqSZrCHMCRL-LEEqQK2n4yQO-o"); var backgrounds = []; var sheet = spreadsheet.getSheetByName("シート1"); var targetRange = sheet.getRange(2, 1, 100, 100); var values = targetRange.getValues(); for(var rowIndex = 0; rowIndex < values.length; rowIndex++) { var row = values[rowIndex]; var backgroundRow = []; for(var colIndex = 0; colIndex < row.length; colIndex++) { var value = row[colIndex]; if (value == "hoge") { backgroundRow.push("yellow"); } else { backgroundRow.push(""); } } backgrounds.push(backgroundRow); } targetRange.setBackgrounds(backgrounds); } 良いコード
33.
①悪い部分を知る
34.
? 遅い理由を知らないとどこを直してよいかわか りません – 実行トランスクリプトを使ってどこに時間がかかっ ているか確認する ①悪い部分を知る
35.
①悪い部分を知る
36.
②無駄なAPIアクセス を減らす
37.
? GASのService呼び出しは全てネットワーク経由で行 われるため、時間がかかります。 少しでも無駄な呼び出しはしないようにします。 ②減らす ネットワーク経由
38.
function badCode() { var
spreadsheet = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqS ZrCHMCRL-LEEqQK2n4yQO-o/edit#gid=0"); for(var row = 2; row <= 101; row++) { for(var col = 1; col <= 100; col++) { var value = spreadsheet.getSheetByName("シート1").getRange(row, col).getValue(); if (value == "hoge") { spreadsheet.getSheetByName("シート1").getRange(row, col).setBackground("yellow"); } } } } ②減らす
39.
function badCode() { var
spreadsheet = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqSZrCHMCRL- LEEqQK2n4yQO-o/edit#gid=0"); var sheet = spreadsheet.getSheetByName("シート1"); for(var row = 2; row <= 101; row++) { for(var col = 1; col <= 100; col++) { var range = sheet.getRange(row, col); var value = range.getValue(); if (value == "hoge") { range.setBackground("yellow"); } } } } ②減らす
40.
③なるべく1度にする
41.
? ②同じ原理でより呼び出し回数を減らすために getValues,setBackgrounds等のBatch Operationを 利用します。 ③1度にする 通常のgetValue() getValue() 1セルで1回アクセス
= 100×100回アクセス
42.
? ②同じ原理でより呼び出し回数を減らすために getValues,setBackgrounds等のBatch Operationを 利用します。 ③1度にする getValues() getValues) 100×100セルを1回アクセス
= 1回アクセス
43.
function badCode() { var
spreadsheet = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqSZrCHMCRL- LEEqQK2n4yQO-o/edit#gid=0"); var sheet = spreadsheet.getSheetByName("シート1"); for(var row = 2; row <= 101; row++) { for(var col = 1; col <= 100; col++) { var range = sheet.getRange(row, col); var value = range.getValue(); if (value == "hoge") { range.setBackground("yellow"); } } } } ③1度にする
44.
function badCode() { var
spreadsheet = SpreadsheetApp .openByUrl("https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqSZrCHMCRL-LEEqQK2n4yQO-o/edit#gid=0"); var backgrounds = []; var sheet = spreadsheet.getSheetByName("シート1"); var targetRange = sheet.getRange(2, 1, 100, 100); var values = targetRange.getValues(); for(var rowIndex = 0; rowIndex < values.length; rowIndex++) { var row = values[rowIndex]; var backgroundRow = []; for(var colIndex = 0; colIndex < row.length; colIndex++) { var value = range.getValue(); if (value == "hoge") { backgrounds.push("yellow"); } else { backgrounds.push(“"); } } backgrounds.push(backgroundRow); } targetRange.setBackgrounds(backgrounds); } ③1度にする
45.
? 大体のスクリプトはこの②、③を実施すればかなりパ フォーマンスが良くなります。
46.
④ 我に返る
47.
? 今回の処理はGASでやる必要がありません。 Sheetsの標準機能でやれることはそっちでやりましょ う – 今回のはセルの条件付き書式でできます。 –
新しいSpreadsheetはかなり細かい書式が使えるので 確認して下さい。 ④我に返る
49.
辞辫别苍叠测滨诲と辞辫别苍叠测鲍谤濒
50.
? Spreadsheet,Forms自体などを取得する際に利用す る辞辫别苍叠测滨诲と辞辫别苍叠测鲍谤濒というメソッドが有ります。 ? これらは比較的openByIdの方が速い –
IDはURL中のなんかよくわかない文字の部分がだいたいそれ openByIdとUrl https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqSZrCHMCRL-LEEqQK2n4yQO- o/edit#gid=0
51.
UiApp
52.
? UiAppを利用するときはなるべくClientHandler等ク ライアントサイドで動くイベントハンドラを活用する – UiAppのイベントハンドラは上記以外は全てサーバコールに なりおっそい –
適切にClientHandlerを利用するとかなりUXがよくなる UiApp
53.
HtmlService
54.
? HtmlServiceのパフォーマンスを良くする書き方の話も公式 ページに乗っている HtmlService
55.
? 基本的には – データの取得は非同期に行う ?
doGet内などHtmlService呼び出し前に行わない – <html>,<head>,<body>タグなどは利用しない ? cajaにより自動的に<caja-v-html>に変えられるので意味が無い ? 変えられる分時間がかかるので使わない – Javascriptは最後に読み込む ? <script>タグはファイルの一番末尾に書いておく ? そのほうが画面が表示されてからクライアントサイドのJavascriptが実行される HtmlService
56.
? 大橋の感覚として – 外部のJSやCSSは使わない方が良い ?
使う場合は<script src=/slideshow/gas-best-practice/37555762/“xxx”>とはせず、<script>ここにコピペ</script>して、埋 め込んでしまう。 ? cajaはGoogle経由で外部JS、CSSを取得するので遅い – 画面遷移はJavascriptを使って一部分だけ切り替える ? doGetを毎回すると遅い ? SPA(Single Page Application)の様にJSで画面を切り替えたほうが速い ? というより画面切り替えはしないほうが良い HtmlService
57.
どうしても遅い
58.
? どうしても遅い時は… – UrlFetchAppを利用してGoogle
APIを直接呼び出す。 – 直接呼び出すと、欲しいデータが1回の操作で取得できる場 合がある ? CalendarAppやDriveAppなどでよくある ? fieldsパラメータを利用すると不要なデータを取得しない ためネットワーク的にも良い どうしても遅い
59.
? どうしても遅い時は… – 本当にリアルタイム(わざわざ人が待って)でやる必 要があるか考える ?
Triggerを利用して遅延実行 & 通知でも良いのではない か? ? 朝一回実行すれば大丈夫なんじゃないか? ? 実行タイミングは定期的でも良いのじゃないか? どうしても遅い
60.
? どうしても遅い時は… – ちゃんとGASで作って良いのか考える –
金で解決できるのならGAEやGCPを使ったほうが良 い – SpreadsheetをDBとして使っている場合もそう ? 大量のデータなら場合によってはFusion Table もっと多いならBigQueryを検討 どうしても遅い
62.
まとめ
63.
GASで 困ったら
64.
#gasja
65.
Google Apps API
Japan http://goo.gl/FcU0C
66.
@soundTricker318 http://goo.gl/ZpUOs
67.
会社: http://goo.gl/CfVPf 個人: http://goo.gl/kVTv3
Editor's Notes
#30:
https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqSZrCHMCRL-LEEqQK2n4yQO-o/edit#gid=0
#32:
https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqSZrCHMCRL-LEEqQK2n4yQO-o/edit#gid=0
#49:
https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqSZrCHMCRL-LEEqQK2n4yQO-o/edit#gid=0
#62:
https://docs.google.com/spreadsheets/d/1kzi8pXTZZrABgTGbJFqSZrCHMCRL-LEEqQK2n4yQO-o/edit#gid=0
Download