繁体   English   中英

数组比在Google Scripts中访问Google表格单元格快多少?

[英]How much faster are arrays than accessing Google Sheets cells within Google Scripts?

在Google脚本中访问和操作数组与访问和操作Google工作表中的数据相比要快多少?

这是应用程序:

我正在制定一个为员工创建计划的计划。 我的策略是创建每天可用员工的列表,随机化列表,然后根据特定参数逐个将随机员工插入每​​个打开的插槽。 然后重复一周中的每一天,直到计划完成。

有时在给定随机列表的情况下不满足参数,我需要重新启动循环。 平均而言,我将运行~1100次循环迭代,直到计划被填满。 如果GoogleScript运行> 6分钟,则会导致该功能超时并自动停止。

我的功能是访问来自GoogleSheets的数据并直接从函数中的数组访问数据。 一般来说,重写我的函数是否会有明显的差异,以便所有数据都直接在数组中存储和操作?

影响程度将取决于您正在做多少读写。 如果当前使用了大量增量数据传输,那么改变您的方法可以带来巨大的好处。

调用Spreadsheet API通常需要0.01秒或更长时间才能完成。 调用导入/导出数据或调用子函数将需要更长时间(例如getDataRangegetValue(s)setValue(s) )。 Apps脚本非常智能,可以优化一些连续的调用,但如果你是交替读写,那么Google端的任何内容都无法帮助你。
您可以在View -> Execution Transcript菜单上查看此计时数据。

我的建议是将任何现有的基于单元格的验证公式移动到脚本函数中,这些函数对传递的员工名称进行操作,员工之间的对象映射以及他们已经“工作”的班次,以及建议的转换工作。 然后,您可以使用1次呼叫导入员工日可用性列表,并且对于每个班次,每天都要验证随机选择的可用员工是否可以使用它,因为他们之前在调度期间进行了调整。 最后,您将对象写回工作表。


时间脚本(由于连续读取而由谷歌进行内部优化)

function writeRand_(rows, cols)
{
  var datasheet = SpreadsheetApp.openById(ssid).getSheetByName('Sheet1');
  datasheet.getDataRange().clearContent();
  var rand = [];
  for(var row = 0; row < rows; ++row)
  {
    var data = [];
    for(var col = 0; col < cols; ++col)
      data.push(Math.random());
    rand.push(data);
  }
  datasheet.getRange(1, 1, rand.length, rand[0].length).setValues(rand);
  return datasheet;
}

function readAndTime()
{
  var rows = 50, cols = 8;
  var datasheet = writeRand_(rows, cols);
  // sum one-by-one
  var sum1 = 0;
  var startRangeSum = new Date().getTime();
  for(var row = 1; row <= rows; ++row)
    for(var col = 1; col <= cols; ++col)
      sum1 += datasheet.getRange(row, col).getValue()-0;
  var endRangeSum = new Date().getTime();
  // Read all, then sum.
  var sum2 = 0;
  var startArraySum = new Date().getTime();
  var inputs = datasheet.getDataRange().getValues();
  for(var row = 0; row < inputs.length; ++row)
    for(var col = 0; col < inputs[0].length; ++col)
      sum2 += inputs[row][col]-0;
  var endArraySum = new Date().getTime();
  Logger.log("Value count: " + rows * cols);
  Logger.log("Range sum: " + (endRangeSum - startRangeSum)/1000 + " sec. " + sum1);
  Logger.log("Array sum: " + (endArraySum - startArraySum)/1000 + " sec. " + sum2);
}

上面给出了~8s的范围和.2s的数组 - 而.2s基本上都是由于调用getDataRange()来进行inputs所需的时间

tehhowch说得恰当=)我这样做。

/* The first couple of nested loops use only reading methods as well as based on this 
    they pick up cells whose value must be changed in the array for next loop
*/

for (var rowIndex = editedCell.getRow(); rowIndex <= wageGrid.getLastRow(); rowIndex++) {
  if (weBreak) break;

  for (var collIndex = (rowIndex == editedCell.getRow()) ? (editedCell.getColumn() + 1) : wageGrid.getColumn(); collIndex <= wageGrid.getLastColumn(); collIndex++) {

    var cell = aSheet.getRange(rowIndex, collIndex);
    var cellFontColor = cell.getFontColor();
    var cellYearAndMonth = aSheet.getRange(rowIndex, 1).getValue();
    var cellDay = aSheet.getRange(1, collIndex).getValue();

    if (cellFontColor == "#ff0000") {

      weBreak = true;
      break;
    }
    if (aSheet.getRange(rowIndex, 1).getValue().getMonth() == cellYearAndMonth.getMonth()) {

      cellsToSetValue.push(cell);
    }
  }
}

//the next loop has an array of cell and perform only "set" methods

for (var cellIndex = 0; cellIndex <= cellsToSetValue.length; cellIndex++) {

  cellsToSetValue[cellIndex].setValue(evt.value);
}

因此,当API优化“获取”和“设置”方法的工作时,只有两个延迟,并且它们之间的一切都快速可忍受)

暂无
暂无

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

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