Conseils d’optimisation

4D - Documentation   Français   English   German   Español   Japanese   4D v11 SQL, Commandes par thèmes   4D v11 SQL, Liste alphabétique des commandes   4D v11 SQL, Constantes par thèmes   Retour   Précédent   Suivant

version 2003 (Modifiée)


Il est difficile, voire impossible, de consigner une fois pour toutes des instructions pour "bien programmer". Tout au plus pouvons-nous renouveler les recommandations générales vous invitant à bien structurer vos programmes, grâce notamment aux possibilités de programmation générique offertes par 4D.

De fait, il est clair que si vous essayez de compiler une base très bien structurée, vous obtiendrez de bien meilleurs résultats que si votre base est mal structurée. Par exemple, si vous écrivez une méthode projet générique qui gère n méthodes objet, vous obtiendrez de bien meilleurs résultats, en interprété comme en compilé, que si les n méthodes objet comportent n fois les mêmes séquences d'instructions.

La qualité de votre programmation peut donc avoir des effets sur la qualité du code compilé.

Si vous débutez, vous améliorerez progressivement votre code 4D grâce à l'habitude. De la même façon, c'est en utilisant fréquemment le compilateur que vous acquerrez les réflexes qui permettent inconsciemment d'aller droit au but.

En attendant cependant, voici quelques conseils et astuces qui vous permettront de gagner du temps dans des opérations simples et fréquentes.

Remarque préliminaire : les commentaires


Certaines astuces que nous vous conseillons peuvent rendre votre code moins lisible par une personne extérieure ou par vous-même ultérieurement. En conséquence, n'hésitez pas à assortir vos méthodes de commentaires détaillés. En effet, si les commentaires peuvent parfois ralentir une base interprétée, ils n'ont strictement aucune influence sur les temps d'exécution d'une base compilée.

Optimisation par les directives de compilation


Les directives de compilation peuvent vous aider à accélérer considérablement votre code.

Par défaut, le compilateur donne le type le plus large possible à vos variables afin de ne pas vous pénaliser. Si vous ne typez pas par une directive de compilation une variable désignée par l'instruction Var:= 5, le compilateur lui donnera le type Réel, même s'il s'agit de l'affectation d'une valeur entière. Nous allons maintenant voir comment, dans certains cas, déclarer une variable peut vous faire gagner beaucoup de temps.

Numériques

Par défaut, le compilateur donne le type Réel (numérique) aux variables numériques non typées par directive de compilation et si les Préférences n'indique pas le contraire. Or, les calculs sur un Réel sont plus lents que sur un Entier. Lorsque vous êtes sûr qu'un de vos numériques s'exprimera toujours dans votre base sous forme d'un Entier, il est avantageux de le déclarer par les directives de compilation C_ENTIER ou C_ENTIER LONG.

Une bonne habitude à prendre, par exemple, est de systématiquement déclarer vos compteurs de boucles comme Entier par directive de compilation.

Par ailleurs, certaines fonctions standard de 4D renvoient des Entiers (exemple : Code de caractere, Ent...). Si vous affectez le résultat d'une de ces fonctions à une variable non typée de votre base, le compilateur lui donnera le type Numérique et non Entier. Pensez donc à déclarer ces variables par des directives de compilation si vous êtes certain qu'elles ne seront utilisées que dans ces conditions.

Prenons un exemple simple. Une fonction renvoyant une valeur aléatoire comprise entre deux bornes peut s'écrire :

   $0:=Modulo(Hasard;($2-$1+1))+$1

Elle renvoie toujours une valeur entière. Si cette fonction est écrite ainsi, le compilateur donnera à $0 le type Numérique et non le type Entier ou Entier long. Il est donc préférable d'écrire cette méthode sous la forme :

   C_ENTIER LONG($0)
   $0:=Modulo(Hasard;($2-$1+1))+$1

Le paramètre rendu par la méthode sera plus petit et il sera donc plus rapide de faire appel à cette méthode.

Prenons un autre exemple simple. Supposons que vous ayez déclaré deux variables en Entier long par l'instruction suivante :

   C_ENTIER LONG($var1;$var2)

et qu'une troisième variable non typée reçoive la somme des deux autres :

   $var3:=$var1+$var2. 

Il vous faudra explicitement déclarer $var3 comme Entier long si vous voulez effectivement que $var3 soit de type Entier long, sinon le compilateur la typera par défaut en Numérique.

Note : Attention au mode de calcul dans 4D. En mode compilé, ce n'est pas le type de la variable recevant le calcul qui détermine le mode de calcul, mais le type des opérandes.

Dans l'exemple ci-dessous, le calcul s'effectue sur des Entiers longs :

   C_REEL($var3)
   C_ENTIER LONG($var1;$var2)
   $var1:=2147483647
   $var2:=1
   $var3:=$var1+$var2

$var3 prendra la valeur –2147483648 en mode compilé comme en interprété.

Dans l'exemple suivant :

   C_REEL($var3)
   C_ENTIER LONG($var1)
   $var1:=2147483647
   $var3:=$var1+1

pour des raisons d'optimisation, le compilateur considère la valeur 1 comme une valeur entière. $var3 prendra alors la valeur –2147483648 en mode compilé (car le calcul s'effectue sur des Entiers longs) et 2147483648 en mode interprété (car le calcul s'effectue sur des Réels).

Les boutons sont un cas particulier de Numérique qu'il est possible de déclarer en Entier long.

Chaînes de caractères

De même que pour les numériques, le compilateur donne par défaut le type Texte à vos variables alphanumériques, si les Préférences n'indiquent pas le contraire. Si vous écrivez :

MaChaine:="Bonjour", MaChaine sera pour le compilateur une variable de type Texte.

Si vous avez beaucoup de traitements à effectuer sur cette variable, il est avantageux de la déclarer explicitement à l'aide de la directive C_ALPHA. Les traitements sont en effet beaucoup plus rapides sur les variables de type Alpha dont la longueur maximale est définie, que sur les variables de type Texte. N'oubliez pas cependant les règles de comportement de cette directive.

Si vous souhaitez tester la valeur d'un caractère, il est plus rapide de faire la comparaison sur son Code de caractere que sur le caractère lui-même. En effet, la routine standard de comparaison de caractères prend en compte toutes les variations du caractère, comme par exemple les accentuations.

Remarques diverses


Tableaux à deux dimensions

Les traitements sur les tableaux à deux dimensions seront mieux gérés si la deuxième dimension est plus grande que la première.

Par exemple, un tableau déclaré sous la forme :

   TABLEAU ENTIER(LeTableau;5;1000)

sera mieux géré qu'un tableau déclaré sous la forme :

   TABLEAU ENTIER(LeTableau;1000;5)

Champs

Vous gagnerez du temps lorsque, si vous devez effectuer plusieurs calculs sur un champ, vous rangez la valeur de ce champ dans une variable et que vous effectuez vos calculs sur cette variable, plutôt que de faire directement les calculs sur le champ. Illustrons notre propos par un exemple. Prenons la méthode suivante :

   Au cas ou
      : ([Client]Dest="Paris")
         Transport:="Coursier"
      : ([Client]Dest="Corse")
         Transport:="Avion"
      : ([Client]Dest="Etranger")
         Transport:="Service express"
      Sinon
         Transport:="Poste"
   Fin de cas

La séquence ci-dessus sera plus lente à exécuter que si elle avait été écrite de la façon suivante :

   $Dest:=[Client]Dest
   Au cas ou
      : ($Dest="Paris")
         Transport:="Coursier"
      : ($Dest="Corse")
         Transport:="Avion"
      : ($Dest="Etranger")
         Transport:="Service express"
      Sinon
         Transport:="Poste"
   Fin de cas

Pointeurs

De même que pour les champs, il est plus rapide de travailler sur une variable intermédiaire que sur un pointeur dépointé. Vous gagnerez énormément de temps si, lorsque vous devez faire plusieurs calculs sur une variable pointée, vous rangez le pointeur dépointé dans une variable.

Vous disposez par exemple d'un pointeur pointant sur un champ ou sur une variable, MonPtr. Ensuite, vous souhaitez faire une série de tests sur la valeur pointée par MonPtr. Vous pouvez écrire :

   Au cas ou
      : (MonPtr-> = 1)
         Séquence 1
      : (MonPtr-> = 2)
         Séquence 2
      …
   Fin de cas

Il est plus rapide d'exécuter cette série de tests si elle est écrite ainsi :

   Temp:=MonPtr->
   Au cas ou
      : (Temp = 1)
         Séquence 1
      : (Temp = 2)
         Séquence 2
      …
   Fin de cas

Variables locales

Utiliser des variables locales permet, dans bien des cas, de mieux structurer son code. Ces variables présentent d'autres avantages :

Les variables locales prennent moins de place en mémoire lors de l'utilisation d'une base : en effet, elles sont créées lorsqu'on entre dans la méthode où elles sont utilisées et détruites dès qu'on sort de cette méthode.

Le code généré est optimisé pour les variables locales, en particulier de type Entier long. Pensez-y pour vos compteurs de boucle.

Référence

Guide du typage, Messages d'erreurs, Précisions de syntaxe, Utilisation des directives de compilation.


4D - Documentation   Français   English   German   Español   Japanese   4D v11 SQL, Commandes par thèmes   4D v11 SQL, Liste alphabétique des commandes   4D v11 SQL, Constantes par thèmes   Retour   Précédent   Suivant