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

标签 javascript arrays google-apps-script google-sheets

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

这是应用程序:

我正在开发一个为员工制定时间表的程序。我的策略是为每天创建一个可用员工列表,将列表随机化,然后根据特定参数将随机员工逐一插入每个空缺位置。然后重复一周中的每一天,直到排满为止。

有时给定的随机列表不满足参数,我需要重新启动循环。平均而言,我将运行约 1100 次循环迭代,直到排满为止。如果 GoogleScript 运行超过 6 分钟,则会导致函数超时并自动停止。

我的函数混合了从 GoogleSheets 访问数据和直接从函数中的数组访问数据的功能。一般来说,重写我的函数以便所有数据都直接存储在一个数组中并在数组中进行操作会有明显的不同吗?

最佳答案

影响的大小取决于您的阅读和写作量。如果当前使用大量增量数据传输,那么改变您的方法可以产生巨大的 yield 。

对电子表格 API 的调用通常需要 0.01 秒或更长时间才能完成。导入/导出数据或调用子函数的调用将花费更长的时间(例如 getDataRangegetValue(s)setValue(s) ). Apps Script 足够智能,可以优化一些连续的调用,但如果您交替进行读写操作,那么 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

关于javascript - 数组比访问 Google Scripts 中的 Google 表格单元格快多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49020131/

相关文章:

google-apps-script - 如何从 Google 文档脚本授权和发布/更新 Trello 卡

javascript - 条形图中的链接 (charts.js)

c - 带有 Char 数组的结构正在打印垃圾...如何解决?

c# - 在 C# 类库中使用 MATLAB MWArray.dll

google-apps-script - 在 Google Apps 脚本中使用 Adwords API (MccApp)

javascript - Apps Script JS 将范围内的项目添加到数组(如果尚未在数组中)失败

javascript - 如何隐藏除我的位置之外的谷歌地图兴趣点?

javascript - Angular 2 forEach 无法读取属性

javascript - 如何将进度圈限制在 60 而不是 100% 以内

javascript - 如何只显示包含对象的数组?