Loop или Array Map, что быстрее? Как мне перейти от вложенных циклов к методу карты массива в скрипте Google?

Как я могу ускорить приведенный ниже код? Я считаю, что метод Array Map ускорит работу, но я не знаю, как это реализовать из-за вложенного цикла. Может быть, есть какой-то другой способ, о котором я не знаю? Я больше знаком с VBA и очень медленно пытаюсь изучить Google Script!

var document = XmlService.parse(response);
  var root = document.getRootElement();
  var NS = XmlService.getNamespace("urn:ebay:apis:eBLBaseComponents");
   
  var ack = root.getChildText('Ack', NS);
  var time = root.getChildText('Timestamp', NS);
  var version = root.getChildText('Version', NS);
  var build = root.getChildText('Build', NS);
  var shortmessage = root.getChildText('ShortMessage', NS);
  var longmessage = root.getChildText('LongMessage', NS);
 
  var sr = root.getChildren('SaleRecord', NS);    
  
  for (var i = 0; i < sr.length; i++) {
      
    var orderids = sr[i].getChildren('SellingManagerSoldTransaction', NS);
    
    for (var L = 0; L < orderids.length; L++) {      
     
    var srn = orderids[L].getChild('SaleRecordID', NS).getText();

    var sku = orderids[L].getChild('CustomLabel', NS).getText();
      
    var title = orderids[L].getChild('ItemTitle', NS).getText();

    var qty = orderids[L].getChild('QuantitySold', NS).getText();  
        
    var lineitem = orderids[L].getChild('OrderLineItemID', NS).getText();    
   
    var name = sr[i].getChild('ShippingAddress', NS).getChild('Name', NS).getText();
    var pcode = sr[i].getChild('ShippingAddress', NS).getChild('PostalCode', NS).getText();
    var status = sr[i].getChild('OrderStatus', NS).getChild('CheckoutStatus', NS).getText();
    var paidtime = sr[i].getChild('OrderStatus', NS).getChild('PaidTime', NS).getText();
    var shipped = sr[i].getChild('OrderStatus', NS).getChild('ShippedStatus', NS).getText();
    var email = sr[i].getChild('BuyerEmail', NS).getText();
    var price = sr[i].getChild('SalePrice', NS).getValue();
    var totprice = sr[i].getChild('TotalAmount', NS).getValue();
    
    sheet.appendRow([srn, sku, title, qty, price, totprice, lineitem, name, pcode, status, paidtime, shipped, email]);
      
      }
XML Response Example:

person Razz    schedule 07.10.2020    source источник
comment
На самом деле это не циклы, основное время будет связано с sheet.appendRow(). Ознакомьтесь с рекомендациями в документации.   -  person TheMaster    schedule 08.10.2020
comment
Где я могу найти лучшие практики для sheet.appendRow()? Погуглив, я нашел еще одну страницу в стеке, где предлагалось использовать range.setValues(array). Может быть, я должен изучить это?   -  person Razz    schedule 08.10.2020
comment
Да   -  person TheMaster    schedule 08.10.2020
comment
Итак, я прав, что вы подталкиваете меня к тому, чтобы сначала записать «все» данные в массив, а затем одним нажатием записать их на лист?   -  person Razz    schedule 08.10.2020
comment
Ага   -  person TheMaster    schedule 08.10.2020
comment
Итак, @TheMaster я нашел метод .push. Я добавил и пустой массив перед циклом, заменил .appendRow() на '.push()', затем после того, как цикл добавил sheet.getRange(sheet.getLastRow() + 1, 1, arr.length, arr[0].length).setValues(arr);, и все готово, все работает. Но, что более важно, оооочень быстрее, чем раньше. Спасибо, парни!   -  person Razz    schedule 09.10.2020


Ответы (1)


Отвечать

Вы должны использовать текущий цикл. Просмотр кода с помощью цикла for — хороший вариант.

Поскольку скрипт Google Apps теперь использует V8, этот вопрос эквивалентен вопросу ES6 о циклах for. Когда дело доходит до производительности, вы должны помнить о нескольких вещах.

  • У вас есть разные способы перебора массива, и вы не можете решить, какой вариант лучше, не помня, что вы собираетесь с ним делать.

  • Вы просто добавляете новую строку в свой лист, поэтому ни карта, ни forEach здесь не быстрее, чем цикл for.

Краткое объяснение

Есть много вариантов перебора массива: forEach, map, for, for...of, filter и т. д.

Если вы хотите создать новый массив с новыми значениями для существующего массива, вы должны использовать map вместо этого, потому что map выделяет память и сохраняет возвращаемое значение в функции обратного вызова. Эта функция создает и возвращает массив, поэтому вам не следует использовать ее в данном конкретном случае, если только вы не хотите возвращать массив, содержащий некоторые значения.

С помощью forEach зациклить производительность зависит от того, что происходит внутри каждой итерации. Эта функция имеет функцию обратного вызова для изменения текущего массива, поэтому обычно она немного медленная в зависимости от размера массива.

В противном случае при использовании for производительность зависит только от того, сколько времени занимают getChildren(), getChild() и sheet.appendRow().

person Jose Vasquez    schedule 08.10.2020