Como optimizar la escritura en spreadsheets mediante SetValues de Google Apps Script

Artículo relacionado con la optimización de código de Google Apps Script

Una cosa muy típica que nos pasa a todos los que programamos en Google Apps Script al empezar es que tenemos que escribir información en un spreadsheet y está operación se vuelve horriblemente lenta.

De hecho aún recuerdo en alguno de mis primeros scripts en que físicamente podía ver como iba escribiendo casilla a casilla los valores en cada celda.

Si el tiempo no nos preocupa , ok, pero generalmente nos interesará que nuestros scripts se ejecuten en el mínimo tiempo posible.

Una manera muy sencilla de optimizar la escritura en spreadsheets es utilizar SetValues en vez de SetValue. Con un ejemplo lo veremos más claro.

Imaginemos que tenemos que hacer una función que nos imprima un contador incremental en una matriz de NxN , donde N es un parámetro que nos pasan a la función.

La forma "novata" de implementarlo sería la siguiente:
function TestVelocidadSetValue(n)
{
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var cont = 0;
  for(var i = 0 ; i < n ; ++i)
  {
     for(var j = 0 ; j < n ; ++j)
     {
        sheet.getRange(i+1, j+1).setValue(cont++);
     }
  }
}

Para valores pequeños de N no habría mucho problema, pero si N fuera grande (200 por ejemplo) la función tardaría bastante. Para solucionar esto podríamos usar un código un poco más "profesional":
function TestVelocidadSetValues(n)
{
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var cont = 0;
  var buffer = new Array(n);
  for(var i = 0 ; i < n ; ++i)
  {
    buffer[i] = new Array(n);
     for(var j = 0 ; j < n ; ++j)
     {
       buffer[i][j] = cont;
       cont++;
     }
  }

   sheet.getRange(1, 1,n,n).setValues(buffer);
}

Todo lo que hemos hecho es no imprimir directamente sobre el spreadsheet sino guardar todos los valores en un buffer (un array bidimensional) para luego volcar este en el spreadsheet.

Cual es la mejora? La siguiente tabla os dará la comparación de tiempos en segundos .

NSetValueSetValuesRatio
100,1250,0373,378378378
10010,0120,26837,35820896
20039,6762,38516,63563941

Como podéis observar para casos pequeños la mejora ayudará a optimizar el rendimiento general de la aplicación pero para casos grandes significará la diferencia entre poder hacer algo a tiempo real o no, o incluso podrá marcar la diferencia entre que nuestra función sea ejecutable o no (pensad que aquí solo imprimimos un número pero podría ser que tuviéramos que calcular algo más complejo y que el total de tiempo excediera el máximo de tiempo permitido por ejecución)

Espero que os sirva . Si tenéis dudas al respecto no vaciléis en poner un comentario.

Nos vemos


1 comentario:

  1. Muchísimas gracias por la aportación!!

    Aquí os dejo un pequeño manual con otras dos formas de adaptar algunos procesos de escritura: https://www.linkedin.com/pulse/c%C3%B3mo-resolver-el-problema-de-m%C3%A1ximo-tiempo-ejecuci%C3%B3n-alcanzado-prada?trk=mp-reader-card

    Enhorabuena por el blog.
    Un saludo
    Javier

    ResponderEliminar

Related Posts Plugin for WordPress, Blogger...