AppleScript et Vitesse


Un problème crucial d'AppleScript c'est sa vitesse d'exécution. Très souvent un simple changement dans la structure du script permet des gains de vitesse de l'ordre de 1 à 10, parfois même beaucoup plus...
Si vous même vous avez accéléré l'éxécution d'un script, vous pouvez en faire profiter tous les autres "AppleScripters", il suffit de nous contacter à applescript.pratique@online.fr
 
 
Les temps d'exécution sont plus long à l'intérieur de cette structure. Il est donc préférable de prendre les informations dans des variables puis de traiter ces informations en dehors de cette structure.
 
Avant
Tell application "AppleWorks"
set Var to cells "B1" thru "B52" of spreadsheet of document 1
set NbVar to count item in Var
repeat from m in NbVar
....
end repeat
end Tell

 
Après :
Tell application "AppleWorks" to set Var to cells "B1" thru "B52" of spreadsheet of document 1
set NbVar to count item in Var
repeat from m in NbVar
....
end repeat

 
La structure Tell application ... end tell peut être simplifiée lorsqu'il n'y a qu'une ligne de programme. Ainsi :
Tell application "AppleWorks"
set Var to cells "B1" thru "B52" of spreadsheet of document 1
end tell
peut s'écrire :
Tell application "AppleWorks" to set Var to cells "B1" thru "B52" of spreadsheet of document 1

Il en est de même pour la structure if.. end if. Ainsi:
if NbVar > 40 then
set NbVar to 40
end if

peut s'écrire :
if NbVar > 40 then set NbVar to 40
 
 
Les temps d'exécution sont très longs dans un repeat au nombre de tours élevés. Certains algorithmes permettent de diminuer le nombre de tours, certes il faut faire travailler ses méninges, mais à la fin c'est toujours payant. Exemple : on veut initialiser une variable qui répète 15000 fois {1,2,3,4,5,6,7,8,9}
 
Avant  :
set GVar to ""
set Tempo to time of (current date)
-- permet de mesurer les temps d'exécution.
set Var to {1, 2, 3, 4, 5, 6, 7, 8, 9}
repeat 15000 times
set GVar to GVar &Var
end repeat
set Tempo to (time of (current date)) - Tempo


-> Résultat : 41 s
 
Après :
set Tempo to time of (current date)
set Var to {1, 2, 3, 4, 5, 6, 7, 8, 9}
set GVar to Var
repeat 10 times
set GVar to GVar & GVar
end repeat
set GVar2 to items 1 thru 9000 of GVar
set GVar to ""
repeat 15 times
set GVar to GVar & GVar2
end repeat
set Tempo to (time of (current date)) - Tempo

-> Résultat : 1 s
 
Le test a été effectué sur un Imac première génération.
Le premier script exécute la logique première de ce qui est demandé, à savoir 15000 fois {1,2,3,4,5,6,7,8,9}. Nous arrivons à 135000 éléments.
Le deuxième script, commence par fabriquer cette variable d'une manière exponentielle: 2,4,8,16,32 éléments ... etc. Nous pourrions ainsi arriver très vite à nos 135000 éléments, mais on ne peut pas prendre 135000 items d'un seul coup ... car cette façon de faire arrive rarement au nombre exact d'éléments voulus, il faut donc prendre la partie du résultat obtenu qui nous intéresse.
Donc on va prendre le problème à l'envers : 15000 fois 9 éléments c'est identique à 15 fois 9000 éléments. Cette fois prendre 9000 éléments d'un seul coup est permis (la limitation est de l'ordre de 32 Ko).
Dans un premier temps on fabrique d'une manière exponentielle une variable, dont on prendra les 9000 éléments qui nous intéressent. Restera ensuite à ajouter 15 fois ces 9000 éléments pour arriver au bon résultat.
Le gain de temps est surprenant mais tout à fait réel ! Cela vaut donc le coup de remanier quelques repeat...
 
 
Page 205 de "AppleScript Language Guide for AppleScript 1.3.7 " du 5 mai 1999, nous pouvons lire :
 
Avant  :
-- bigLists est une liste de 4000 entiers
set numItems to 4000
set t to (time of (current date) )
repeat with n from 1 to numItems
item n of bigList
end repeat
set total to (time of (current date)) - t

-> Résultat : 26 s
 
Après :
-- bigLists est une liste de 4000 entiers
set bigListRef to a reference to bigList
set numItems to 4000
set t to (time of (current date) )
repeat with n from 1 to numItems
item n of bigListRef
end repeat
set total to (time of (current date)) - t

-> Résultat : 1 s
 
Plutôt intéressant ce "a reference to", non ?