我正在从外部端点获取的数据中填充一张spreadhsheet。一切正常,但for...in循环的执行速度非常慢。
我从UrlFetchApp回来的对象非常大; Object.keys().length > 1500
,所以它可能只是对象的大小。
我很好奇是否有办法优化我的功能。
代码:
var sh = SpreadsheetApp.getActiveSheet();
function getData() {
var response = UrlFetchApp.fetch(endpoint);
var data = JSON.parse(response);
var rates = data["quotes"];
var max = Object.keys(rates).length;
var row = 2;
var i = 0;
clear(); //clears the range A2:B
for (var key in rates) {
sh.getRange("A" + (i+row)).setValue(key.substring(3));
sh.getRange("B" + (i+row)).setValue(rates[key]);
i++
if (i+1 === max) {
//do something after complete
}
}
}
答案 0 :(得分:5)
我不确定//do something after complete
。那么这两种模式怎么样呢。请将此答案视为几个答案之一。
我修改了您的脚本,将setValue()
替换为setValues()
。这样,处理速度就会很快。
function getData1() {
var sh = SpreadsheetApp.getActiveSheet();
var response = UrlFetchApp.fetch(endpoint);
var data = JSON.parse(response);
var rates = data["quotes"];
var keys = Object.keys(rates);
var dat = [];
keys.forEach(function(key){
if (key != keys[keys.length - 1]) {
dat.push([key.substring(3), rates[key]]);
} else {
//do something after complete
}
});
sh.getRange(2, 1, dat.length, dat[0].length).setValues(dat);
}
function getData2() {
var sh = SpreadsheetApp.getActiveSheet();
var response = UrlFetchApp.fetch(endpoint);
var data = JSON.parse(response);
var rates = data["quotes"];
var dat = Object.keys(rates).map(function(key){return [key.substring(3), rates[key]]});
sh.getRange(2, 1, dat.length, dat[0].length).setValues(dat);
//do something after complete
}
var response = UrlFetchApp.fetch(endpoint);
的样本数据?当然,请从中删除私人信息。如果我误解了你的问题,我很抱歉。
答案 1 :(得分:2)
问题不在于对象的大小。您反复调用sheet.getRange()来获取目标范围内的每个单独的单元格,这是多余的。保持读取/处理/写入操作彼此完全分离,以优化性能。 1)检索值2)处理它们,以及3)在目标范围上调用'setValues()'。完成时间不到0.2秒:
var arr = [];
for (var [prop, val] in hugeObject) {
arr.push([prop, val]);
}
var targetRange = SpreadsheetApp.getActive()
.getSheets()[0]
.getRange(2, 1, arr.length, arr[0].length)
.setValues(arr);