Javascript, HTML, CSS e... !
0 commenti

Le prestazioni sono importanti!

A cosa serve Spreadsheet.flush() e quando conviene usarlo

Per definizione, l'utilità del metodo Spreadsheet.flush() è quella di assicurarsi che il risultato e/o gli effetti del codice appena eseguito vengano apportati o mostrati nel foglio di calcolo prima che lo script prosegua con le operazioni successive.

Nel caso in cui non venga utilizzato il metodo in questione, lo script cercherà di ottimizzare in modo automatico il risultato delle operazioni effettuate nel foglio di calcolo al fine di ottimizzare le prestazioni del codice tramite un sistema di caching, il caso più esemplificativo si ha quando vengono effettuate molte richieste a Range.getValue().
In altri termini, se abbiamo uno script che scrive in 100 celle di uno Spreadsheet ed eseguiamo il metodo flush() dopo ogni operazione di scrittura, il codice si assicurerà di mostrare ogni singolo risultato nell'opportuna cella prima di eseguire il codice per la scrittura della cella successiva. Se invece non facciamo uso del metodo flush() è probabile che vengano scritte le celle una ad una, così come un gruppo di celle alla volta o addirittura tutte insieme, delegando l'ottimizzazione ad Apps Script.

Questo significa che, in linea generale, non è necessario utilizzare il metodo flush() a meno che non abbia senso farlo considerando che il suo utilizzo va ad incidere notevolmente sui tempi di esecuzione del codice (come vedremo di seguito) e per questo motivo le best practice (per maggiori informazioni fare riferimento all'articolo "Google Apps Script: best practice per il miglioramento delle performance") ne sconsigliano l'uso.

Per semplicità di comprensione mi sono avvalso dell'esempio presente nella documentazione ufficiale, relativa al metodo flush(), mantenendone l'approccio ma personalizzandolo per l'occasione aggiungendo funzionalità, inserendo il metodo in questione dopo ogni azione e un contatore del tempo di esecuzione del codice mostrato in un toast a fine esecuzione in modo da evidenziare la differenza di prestazioni espressa in millisecondi (ms) nel caso di utilizzo o meno del metodo flush():

function esempioFlush() {
  var start, stop;
  var doFlush = true; // per disabilitare il metodo flush() modifica il valore in: false
  var sheet = SpreadsheetApp.getActiveSheet();
  start = new Date().getTime();
  
  for (var i = 0; i < 20; i++) {
    if ((i % 2) == 0) {
      sheet.getRange('A1').setBackground('green');
      if (doFlush) SpreadsheetApp.flush();
      sheet.getRange(1, 1, 1, 1).setValue("Lo sfondo della cella è di colore verde");
      if (doFlush) SpreadsheetApp.flush();
      sheet.getRange('B1').setBackground('red');
      if (doFlush) SpreadsheetApp.flush();
      sheet.getRange(1, 2, 1, 1).setValue("Lo sfondo della cella è di colore rosso");
      if (doFlush) SpreadsheetApp.flush();
    } else {
      sheet.getRange('A1').setBackground('red');
      if (doFlush) SpreadsheetApp.flush();
      sheet.getRange(1, 1, 1, 1).setValue("Lo sfondo della cella è di colore rosso");
      if (doFlush) SpreadsheetApp.flush();
      sheet.getRange('B1').setBackground('green');
      if (doFlush) SpreadsheetApp.flush();
      sheet.getRange(1, 2, 1, 1).setValue("Lo sfondo della cella è di colore verde");
      if (doFlush) SpreadsheetApp.flush();
    }
  }
  
  stop = new Date().getTime();
  SpreadsheetApp.getActiveSpreadsheet().toast("Il tempo di esecuzione è stato di " + (stop - start) + "ms", "Esecuzione terminata!", 10);
}

Se provate ad eseguire il codice così com'è, incorporato (bound-script) in uno Spreadsheet (per aprire l'editor di script cliccare nella barra dei menù sulla voce 'Tools' e successivamente sull'elemento 'Script editor...'), ed osservate il comportamento delle celle, noterete che le prime due celle del foglio di calcolo alternano il colore di sfondo da rosso a verde (e contestualmente anche le stringhe di testo in esse contenute) in modo pressoché lineare e continuo in virtù del fatto che SpreadsheetApp.flush() viene invocato ad ogni esecuzione di operazione all'interno del ciclo, Fig. 1:



risultato esempio metodo flush con alternanza celle

Fig. 1 - Risultato dell'esempio utilizzato in questo articolo per mostrare vantaggi e svantaggi del metodo flush()


Nel toast potrete poi verificare il tempo di esecuzione dello script, Fig. 2:



tempo di esecuzione esempio con metodo flush abilitato

Fig. 2 - Tempo di esecuzione del codice di esempio con il metodo flush() abilitato


Se invece modificate il valore della variabile doFlush da true a false, il cui scopo è quello di abilitare/disabilitare l'uso del metodo in questione, ed eseguite adesso lo script per poi osservare il comportamento delle celle, noterete molto probabilmente che l'armonia nell'alternanza delle prime due celle viene a mancare, di contro però il tempo di esecuzione dello script è assai inferiore, Fig. 3:



tempo di esecuzione esempio con metodo flush disabilitato

Fig. 3 - Tempo di esecuzione del codice di esempio con il metodo flush() disabilitato


E' quindi evidente che se lo scopo è mostrare un output all'utente in una determinata fase di esecuzione del codice ha senso avvalersi del metodo Spreadsheet.flush(), altrimenti se ha solo importanza il risultato finale, come dimostrano le prestazioni (considerando che abbiamo lavorato solamente su 2 celle: 13,5 secondi usando il metodo contro i 5,5 secondi senza utilizzarlo), l'unica cosa che ha senso fare con il metodo flush() è... starne alla larga!

Tags

Michele Pisani

Michele Pisani

Sviluppatore Javascript ed esperto in Digital Analytics

L'esperienza nel settore Digital Analytics unita ad anni di sviluppo in Javascript ha trovato la massima espressione in Google Apps Script che mi ha permesso, con estrema facilità e poche righe di codice, di realizzare potenti applicazioni interattive e processi automatizzati integrati con i prodotti della G Suite.

Come contattarmi
scrivi un commento

0 Commenti

Non ci sono commenti

Nessuno ha ancora commentato questo articolo, fallo tu per primo!

scrivi un commento

Scrivi un commento

Il tuo indirizzo email non sarà pubblicato.I campi contrassegnati da un * sono obbligatori
Puoi utilizzare i seguenti tag nei commenti:
[bold]testo[/bold] se vuoi evidenziare un testo con il grassetto[code]function helloworld() { }[/code] se vuoi pubblicare una porzione di codice[url]http://www.appsscript.it[/url] se devi riferirti ad un indirizzo web