什么是速度快:一个ScriptDb或SpreadsheetApp?(What is faster:

2019-07-20 18:37发布

比方说,我有AA脚本,遍历400个对象的列表。 每个对象具有的任何位置从1到10的特性。 每个属性是一个合理的规模字符串或稍微大的整数。

有没有在这些对象保存到一个ScriptDb VS它们保存到电子表格的性能显著差异(W / O在一个批量操作做)。

Answer 1:

ScriptDb中已被弃用。 不使用。



Answer 2:

执行摘要

是的,有一个显著的差异! 巨大! 我不得不承认,这个实验结果并不是我预期的方式。

有了这个数据量,写入到电子表格总是比使用ScriptDb中快得多。

这些实验支持关于在批量操作断言谷歌Apps脚本的最佳实践 。 使用单个电子表格中的数据保存setValues()调用比线由行快75%,并且两个数量级比细胞通过细胞更快。

在另一方面,建议使用Spreadsheet.flush()应慎重考虑,由于对性能的影响。 在这些实验中,4000细胞的电子表格的单个写了小于50ms,并添加调用flush()增加了到610ms -仍然不到一秒钟,但幅度税的命令看起来很荒唐。 调用flush()为每个行400在示例电子表格所作的操作采取几乎12秒,当仅用了164毫秒没有它。 如果你已经经历了超过最长执行时间错误,则可能受益于两家优化代码和删除调用flush()

实验结果

所有的时序,推导出所述的技术以下如何测量通过执行功能所花费的时间 。 时间以毫秒为单位。

下面是使用来自五个不同的方法,两个单程结果ScriptDB ,三写入电子表格,都具有相同的源数据。 (400个对象具有5串5号属性)

实验1

  • 对于一个ScriptDb /对象测试经过时间:53529
  • 对于一个ScriptDb /批量测试经过时间:37700
  • 电子表格/对象的测试经过时间:145
  • 电子表格/属性测试经过时间:4045
  • 用于电子表格/大容量试验经过的时间:32

的影响Spreadsheet.flush()

实验2

在这个实验中,从实验1,唯一的区别是,我们叫Spreadsheet.flush()每个之后setValue/s电话。 这样做的代价是巨大的,(约700%),但不改变使用速度的原因电子表格在ScriptDb的建议,因为写入到电子表格仍然较快。

  • 对于一个ScriptDb /对象测试经过时间:55282
  • 对于一个ScriptDb /批量测试经过时间:37370
  • 电子表格/对象的测试经过时间:11888
  • 电子表格/属性测试经过时间:117388
  • 电子表格/散装测试经过时间:610

注:本实验往往与被杀超过了最大的执行时间

买者自负

您正在阅读这篇文章的interwebs,所以它必须是真实的! 但把它与一粒盐。

  • 这些都是从非常小的样本量的结果,可能不完全重复的。
  • 这些结果测量的东西,不断的变化 - 在2013年2月28日进行观察,而他们,他们测量了当你读到这可能是完全不同的系统。
  • 这些操作的效率由未在这些实验中控制的许多因素的影响; 的指令及中间结果和服务器负载,例如高速缓存。
  • 也许,只是也许,有人在谷歌将阅读,提高ScriptDb中的效率!

代码

如果你想执行(或更好,但改善)这些实验,创建一个空白的电子表格,并复制到其中的一个新的脚本这一点。 这也可以作为一个依据 。

/**
 * Run experiments to measure speed of various approaches to saving data in
 * Google App Script (GAS).
 */
function testSpeed() {
  var numObj = 400;
  var numAttr = 10;
  var doFlush = false;  // Set true to activate calls to SpreadsheetApp.flush()

  var arr = buildArray(numObj,numAttr);
  var start, stop;  // time catchers
  var db = ScriptDb.getMyDb();
  var sheet;

  // Save into ScriptDB, Object at a time
  deleteAll(); // Clear ScriptDB
  start = new Date().getTime();
    for (var i=1; i<=numObj; i++) {
      db.save({type: "myObj", data:arr[i]});
    }
  stop = new Date().getTime();
  Logger.log("Elapsed time for ScriptDB/Object test: " + (stop - start));

  // Save into ScriptDB, Batch
  var items = [];
  // Restructure data - this is done outside the timed loop, assuming that
  // the data would not be in an array if we were using this approach.
  for (var obj=1; obj<=numObj; obj++) {
    var thisObj = new Object();
    for (var attr=0; attr < numAttr; attr++) {
      thisObj[arr[0][attr]] = arr[obj][attr];
    }
    items.push(thisObj);
  }
  deleteAll(); // Clear ScriptDB
  start = new Date().getTime();
    db.saveBatch(items, false);
  stop = new Date().getTime();
  Logger.log("Elapsed time for ScriptDB/Batch test: " + (stop - start));

  // Save into Spreadsheet, Object at a time
  sheet = SpreadsheetApp.getActive().getActiveSheet().clear();
  start = new Date().getTime();
    for (var row=0; row<=numObj; row++) {
      var values = [];
      values.push(arr[row]);
      sheet.getRange(row+1, 1, 1, numAttr).setValues(values);
      if (doFlush) SpreadsheetApp.flush();
    }
  stop = new Date().getTime();
  Logger.log("Elapsed time for Spreadsheet/Object test: " + (stop - start));

  // Save into Spreadsheet, Attribute at a time
  sheet = SpreadsheetApp.getActive().getActiveSheet().clear();
  start = new Date().getTime();
    for (var row=0; row<=numObj; row++) {
      for (var cell=0; cell<numAttr; cell++) {
        sheet.getRange(row+1, cell+1, 1, 1).setValue(arr[row][cell]);
        if (doFlush) SpreadsheetApp.flush();
      }
    }
  stop = new Date().getTime();
  Logger.log("Elapsed time for Spreadsheet/Attribute test: " + (stop - start));

  // Save into Spreadsheet, Bulk
  sheet = SpreadsheetApp.getActive().getActiveSheet().clear();
  start = new Date().getTime();
    sheet.getRange(1, 1, numObj+1, numAttr).setValues(arr);
    if (doFlush) SpreadsheetApp.flush();
  stop = new Date().getTime();
  Logger.log("Elapsed time for Spreadsheet/Bulk test: " + (stop - start));
}

/**
 * Create a two-dimensional array populated with 'numObj' rows of 'numAttr' cells.
 */
function buildArray(numObj,numAttr) {
  numObj = numObj | 400;
  numAttr = numAttr | 10;
  var array = [];
  for (var obj = 0; obj <= numObj; obj++) {
    array[obj] = [];
    for (var attr = 0; attr < numAttr; attr++) {
      var value;
      if (obj == 0) {
        // Define attribute names / column headers
        value = "Attr"+attr;
      }
      else {
        value = ((attr % 2) == 0) ? "This is a reasonable sized string for testing purposes, not too long, not too short." : Number.MAX_VALUE;
      }
      array[obj].push(value);
    }
  }
  return array
}

function deleteAll() {
  var db = ScriptDb.getMyDb();
  while (true) {
    var result = db.query({}); // get everything, up to limit
    if (result.getSize() == 0) {
      break;
    }
    while (result.hasNext()) {
      var item = result.next()
      db.remove(item);
    }
  }
}


文章来源: What is faster: ScriptDb or SpreadsheetApp?