简体   繁体   English

执行for循环非常慢

[英]Very slow execution of for…in loop

I am populating a spreadhsheet from data I am getting from an external endpoint. 我正在从外部端点获取数据填充扩展表。 Everything is working, but the execution of the for...in loop is incredibly slow. 一切正常,但for ... in循环的执行速度非常慢。

The object that I am getting back from UrlFetchApp is quite large; 我从UrlFetchApp获取的对象非常大; Object.keys().length > 1500 , so perhaps it could just be the size of the object. Object.keys().length > 1500 ,所以它可能只是对象的大小。

I am curious if there is a way to optimize my function. 我很好奇是否有办法优化我的功能。

Code: 码:

    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
        }
      }
    }

I was not sure about //do something after complete . 我不确定//do something after complete So how about these 2 patterns. 那么这两种模式怎么样呢。 Please think of this answer as one of several answers. 请将此答案视为几个答案之一。

I modified your script to replace setValue() to setValues() . 我修改了你的脚本,将setValue()替换为setValues() By this, the process speed will be fast. 这样,处理速度将很快。

Pattern 1 : 模式1:

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);
}

Pattern 2 : 模式2:

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
}

Note : 注意 :

  • If this didn't work, can you provide a sample data from var response = UrlFetchApp.fetch(endpoint); 如果这不起作用,您可以提供var response = UrlFetchApp.fetch(endpoint);的样本数据var response = UrlFetchApp.fetch(endpoint); ? Of course, please remove the private information from it. 当然,请从中删除私人信息。

Refecences : 报复:

If I misunderstand your question, I'm sorry. 如果我误解你的问题,我很抱歉。

The problem is not with the size of your object. 问题不在于对象的大小。 You are repeatedly calling sheet.getRange() to get every individual cell in the target range which is redundant. 您反复调用sheet.getRange()来获取目标范围内的每个单独的单元格,这是多余的。 Keep read/process/write operations completely separate from each other to optimize performance. 保持读取/处理/写入操作彼此完全分离,以优化性能。 1) Retrieve values 2) Process them, and 3) Call 'setValues()' on the target range. 1)检索值2)处理它们,以及3)在目标范围上调用'setValues()'。 This took less than 0.2 seconds to finish: 完成时间不到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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM