Temps d'exécution des scripts

Bonjour tout le monde.

J'ai choisi Google Sheets pour son côté "portable". La possibilité d'avoir des feuilles visibles autant sur un mac qu'un PC ou sous Android était pour moi importante.

Il ne m'est pas venu à l'esprit, à ce moment là, de douter de l'efficacité de l'exécution des scripts.

Mais, là maintenant, ce que je constate comme niveau de performance me ramène à une époque préhistorique, c'est simplement incroyable.

Je demande (pour l'instant) très peu de choses au script, mais je comptais bien en faire beaucoup plus dans un 2ième temps.

Pour l'instant, j'ai un simple bout de code qui parcourt une feuille ne contenant que 22 lignes et qui, selon la valeur dans une colonne donnée, décide de faire un "align-gauche/italic" pour les valeurs inférieures à 0 et un "align-droite/normal" pour les autres.

Il lui faut entre 6 et 8 secondes pour ça! pour 22 lignes! et 16 secondes pour 50 lignes, c'est donc proportionnel!

Même en 1990, il y a 30 ans de cela, un tel temps d'exécution pour si peu de choses était impensable.

Juste pour info, ma machine tourne sous windows10, elle est toute neuve et extrèmement performante. Même chose pour ma connexion internet (fibre).

Là, je m'inquiète vraiment sur le choix que j'ai fait, parce que les feuilles à venir seront bien plus lourdes que celles d'aujourd'hui.

Ou alors j'ai mal écrit le script (peut-être qu'il y a quelque chose qui m'échappe).

Je vais joindre le script, d'avance merci et bonne journée.

var wc_premiereLigne = 7;

function credit_debit(){
  var w_sheet = SpreadsheetApp.getActiveSheet();
  var w_maxRow = getMaxRowBySheet(w_sheet);
  var r;
  for (r=wc_premiereLigne; r < w_maxRow; r++){  
    creditDebit(w_sheet, r);  
  }
}

function creditDebit(ww_sheet, ww_row) {
  var w_range = ww_sheet.getRange('C' + ww_row + ':' + 'D' + ww_row);
  if (ww_sheet.getRange(ww_row, 4).getValue() > 0) {
    w_range.setFontStyle('normal');
    w_range.setHorizontalAlignment('right');
  } else {
    w_range.setFontStyle('italic');
    w_range.setHorizontalAlignment('left');
  }
}

function getMaxRowBySheet(ww_sheet){
  var r;
  var w_maxRow = 0;
  for (r=wc_premiereLigne; r<1000 && w_maxRow==0; r++) {
    if (ww_sheet.getRange(r, 2).getValue()=='' && ww_sheet.getRange(r, 3).getValue()=='' && ww_sheet.getRange(r, 4).getValue()=='') { // la date, le total et le détail nulls
      w_maxRow=r; 
      } 
  }
  return w_maxRow;
}

Bon, en fouillant un peu je vois que mon script est mal fichu, dans le sens où il fait une succession de lectures et d'écritures, ce qui empêche l'utilisation du cache.

Si j'ai bien compris ce que j'ai lu, chaque getRange suivi d'un "set" quelconque implique une mise à jour (via internet donc) du cache...

Avant que vous ne répondiez à ma question, je vais quand même essayer de mieux faire.

a+

Bonjour,

Il existe une fonction getLastRow() ... efficace sauf si une colonne entière comporte une check-box par exemple.

Attention aussi à limiter les lignes, inutile d'avoir un fichier avec 1000 lignes et cela peut aussi accélérer.

Pour l'histoire du cache, je suis moins certain, si ton script ne comporte pas de flush() cela ne devrait pas trop impacter ... tu nous diras.

Il n'en comporte aucun (de flush) ma, foi je n'ai pas encore eu le temps de le tester mais quand j'ai lu le truc, ça m'a eu l'air quand même assez crédible. Et de plus ma façon de faire était citée par cet article comme source de problème. Je peux comprendre que chaque écriture suivie d'un getRange implique une mise à jour du cache. On verra. Je vous dirai. Merci pour la fonction getLastRow, je vais l'utiliser ce sera effectivement plus simple.

Bonjour,

Ton problème de lenteur est apparemment dû à tes trop nombreux getRange().getValue()

Dans un cas comme, au lieu d'appeler des milliers de fois getRange().getValue() pour chaque cellule, fais-en un seul et unique pour toute la plage de cellules (enregistre les valeurs de la plage dans un array puis parcours cet array).

Mais dans ce cas précis, tu peux simplement utiliser la fonction proposée par Steelson

Bonjour.

Alors c'est confirmé. Le code n'était pas bon. En regroupant et en utilisant des tableaux, on limite le nombre de "get/set". C'est bien là qu'était le problème.

Pour l'exemple à 50 lignes, je suis passé de 16 secondes à 1!

C'est plus que satisfaisant.

L'exercice est nouveau pour moi (faire tourner du code sur une machine distante pour modifier un objet présent dans mon navigateur).

Il est clair que ça demande une discipline bien plus rigoureuse que ce auquel je suis habitué. Va falloir que je m'y fasse!

En tout cas, je suis rassuré sur le choix que j'ai fait d'utiliser sheets.

Merci encore pour vos avis éclairés.

Je joins de nouveau le script nouvelle version dans le cas où vous jugerez utile de le montrer (pour illustrer).

Bonne journée à vous tous.

98script.txt (1.25 Ko)

Intéressant, merci pour ton code, belle démo.

Rechercher des sujets similaires à "temps execution scripts"