Ускорить доступ к значениям скрипта Google и метаданным? - PullRequest
1 голос
/ 21 ноября 2019

Я написал ряд функций, которые проверяют значения ячеек и используют их для установки других значений ячеек или метаданных разработчика, а также смотрят на метаданные, чтобы решить, что делать. Поскольку я проводил стресс-тестирование функциональности моей электронной таблицы, у меня возникли проблемы, когда запуск сценария для большого диапазона ячеек превысил бы максимальное время выполнения .
Глядя на него, я заметил, что получение и настройка ячейкизначений предварительно определенной ячейки занимает около 0,2 секунды, а поиск и установка метаданных занимает около 0,5–0,8 секунды.
Я написал пример сценария, чтобы показать это, но по какой-то причине время в этом короче, я незнать, связано ли это с тем, что находится в ячейке, или с тем, что таблица меньше или ...
Однако изменив значение на листе, в котором уже есть метаданные для указанного ключа, и запустив этот сценарий:

function onEdit(e){
  timetest(e)
}

function timetest(e) {
  var range = e.range;
  var sheet = range.getSheet();
  for (var r = 1; r <= range.getNumRows(); r++){
    for (var c = 1; c <= range.getNumColumns(); c++){
      var cell = range.getCell(r, c);
      var value = cell.getValue();
      var new_val = value + ' ' + r + c;
      cell.setValue(new_val);
    }
    var metadata = sheet.createDeveloperMetadataFinder().withKey("Updated").find()
    if (metadata.length > 0){
      metadata[0].setValue(new_val)
    } else {
      sheet.addDeveloperMetadata("Updated", new_val, SpreadsheetApp.DeveloperMetadataVisibility.DOCUMENT);
    }
  }
}

дает это

[19-11-21 01:05:44:105 PST] Starting execution
[19-11-21 01:05:44:252 PST] PropertiesService.getDocumentProperties() [0.14 seconds]
[19-11-21 01:05:44:253 PST] SpreadsheetApp.Range.getSheet() [0 seconds]
[19-11-21 01:05:44:254 PST] SpreadsheetApp.Range.getNumRows() [0 seconds]
[19-11-21 01:05:44:254 PST] SpreadsheetApp.Range.getNumColumns() [0 seconds]
[19-11-21 01:05:44:255 PST] SpreadsheetApp.Range.getCell([1, 1]) [0 seconds]
[19-11-21 01:05:44:357 PST] SpreadsheetApp.Range.getValue() [0.101 seconds]
[19-11-21 01:05:44:413 PST] SpreadsheetApp.Range.setValue([p 12 11]) [0.056 seconds]
[19-11-21 01:05:44:413 PST] SpreadsheetApp.Range.getNumColumns() [0 seconds]
[19-11-21 01:05:44:414 PST] SpreadsheetApp.Sheet.createDeveloperMetadataFinder() [0 seconds]
[19-11-21 01:05:44:414 PST] SpreadsheetApp.DeveloperMetadataFinder.withKey([Updated]) [0 seconds]
[19-11-21 01:05:44:682 PST] SpreadsheetApp.DeveloperMetadataFinder.find() [0.267 seconds]
[19-11-21 01:05:44:836 PST] SpreadsheetApp.DeveloperMetadata.setValue([p 12 11]) [0.153 seconds]

Любые идеи о том, что делает эти звонки медленными? Есть ли способ оптимизировать код так, чтобы он работал максимально быстро?

1 Ответ

0 голосов
/ 21 ноября 2019

В ваших вложенных циклах for вы отправляете запросы к getCell(), getValue() и setValue(). Это приводит ко многим удаленным запросам к API Spreadsheets, что замедляет ваш сценарий.

Чтобы значительно повысить производительность вашего сценария, вы можете получить все данные на листе одним единственным вызовом (getValues())примените к нему нужные вам операции, а затем установите его обратно на свой лист, используя еще один вызов (setValues()).

Также я предлагаю вам убрать операции «метаданных» изцикл, так как кажется, что значение имеет только последнее значение new_val. Ваш окончательный код после этих изменений может выглядеть следующим образом:

function onEdit(e){
  timetest(e)
}

function timetest(e) {
  var range = e.range;
  var sheet = range.getSheet();
  var data = range.getValues();
  var new_val;
  for (var i=0; i<data.length; i++) {
    var row = data[i];
    for (var j=0; j<row.length; j++) {
      var value = row[j];
      new_val = value + ' ' + (i+1) + (j+1);
      row[j] = new_val;
    }
  }

  range.setValues(data);

  if (data.length > 0 && data[0].length > 0) {
    var metadata = sheet.createDeveloperMetadataFinder().withKey("Updated").find()
    if (metadata.length > 0){
      metadata[0].setValue(new_val)
    } else {
      sheet.addDeveloperMetadata("Updated", new_val, SpreadsheetApp.DeveloperMetadataVisibility.DOCUMENT);
    }
  }
}

Наконец, я предлагаю вам ознакомиться с Передовой опыт использования скрипта Google Apps .

Квоты

  • Предел выполнения для простых триггеров составляет 30 секунд.
  • При «установке» вашего триггера onEdit этот предел выполнения увеличивается до уровня «нормальной» среды выполнения сценария, то есть 6 минутдля потребителей, G Suite Free и G Suite Basic / Gov и 30 минут для раннего доступа и G Suite Business / Enterprise / Education.
  • Ежедневно допустимая общая продолжительность триггера составляет 90 минут для учетных записей клиентов, 3 часа для G Suiteучетные записи бесплатных изданий и 6 часов для учетных записей более высокого уровня.

Ссылки

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...