Hit-Parade .VB Research Center . Compteur
Accueil ~  Code ~  Programmes ~  Api ~  Forum ~  Cours ~  Livres ~  Quiz ~  Annuaire
~ Edito ~
12/03/2006 @ 13:39
Depuis la dernière mise à jour (qui remonte à... oulala plusieurs mois), un petit ménage de printemps s'impose. Ca tombe bien, c'est presque la période.
Au menu, et progressivement sur les jours à venir, rafraîchissement de plusieurs fonctions et procédures, nouvelles APIs et nouveaux programmes.

~ Rechercher ~

  

~ Annuaire VB ~
 Rechercher un site :
  

~ Partenaires ~

Divers : Optimisation
Optimisation du code VB, et mesure du temps d'exécution.
(Consulté 22802 fois.)

L'optimisation du code c'est bien, mais encore faut-il savoir de quoi on parle !
Voici quelques résultats de mes investigations sur les commandes à utiliser ou à éviter lorsque l'on programme en VB.

Boucle (valeur de lgMax) Commande 1 Temps Commande 2 Temps
10.000.000 Mid( string, x, y ) 17.327 Mid$( string, x, y ) 12.790
10.000.000 Space( x ) 11.842 Space$( x ) 9.124
10.000.000 Trim( string ) 13.842 Trim$( string ) 9.944

Bilan : utilisez de préférences les fonctions typées. En effet, si vous consultez l'aide, vous verrez que Mid, Space, Trim (de même que Left, Right, ... non présents ici), renvoient un type variant, alors que leurs consoeurs, avec la terminaison '$' renvoient des types string. Le type variant, très pénalisant dans VB, justifie donc l'écart. Le rapport n'est pas spécialement important, mais il existe.

Avec le test suivant, vous allez peut-être être étonné.

Boucle (valeur de lgMax) Commande 1 Temps Commande 2 Temps
15.000.000 string = "" 11.935 string = vbNullString 2.599

L'utilisation de la constante vbNullString, proposé en standard par Visual Basic, est plutôt pratique. Egale à Chr$(0) (équivalent à une chaîne vide), cela donne un rapport intérressant. Bien sûr c'est plus long à taper, mais rien n'empêche de continuer à mettre des "" en cours de d'élaboration et de faire des rechercher/remplacer à la fin.

size="2" face="Verdana">Equivalence
L'utilisation de '+' ou de '&' lorsque l'on concatène des chaînes,
string = string1 + string2 prend le même temps que string = string1 & string2

La conversion implicite des nombre dans des chaînes (avec x entier long quelconque),
string = string1 + CStr ( x ) prend autant de temps que string = string1 + x

Faux semblants !!
Voici deux choses dont on m'avait parlé et que je me suis empressé de vérifier. Premièrement il semblait devoir y avoir une différence entre l'utilisation des paramêtres ByRef ou ByVal dans les appels de procédures ou de fonctions, avec un avantage certain à ne pas utiliser ByRef (par défaut sous VB) mais plutôt ByVal.
Voici le résultat de mes tests :

Boucle ByVal ByRef (Vide, par défaut ByRef)
30.000.000 27.085 26.128 25.790

Et Bien, je peux vous dire qu'à partir de 30 millions de tours de boucle la différence n'est évidente (1 sec. d'écart, n'a rien de significatif). Conclusion, je garde mes habitudes, je ne met rien (sauf quand la logique me l'impose!).

Après cela, on m'avait glissé un jour, qu'utiliser la propriétés par défaut d'un objet était plus rapide... Voyons voir...

Boucle Label.Caption Label (par défaut .Caption) Label.Tag
2.000.000 12.687 12.652 3.222
Boucle Text.Text Text (par défaut .Text) Text.Tag
2.000.000 64.662 64.973 3.243

Et bien, les chiffres parlent d'eux même. Pas de différence flagrante. Par contre, le hasard, m'a amené à tester également la propriété Tag. Je l'utilise de temps en temps, et en fin de compte elle n'est pas trop mal placée.

L'appel aux propriétés ou aux méthodes d'un contrôle est toujours très pénalisant, c'est pourquoi le test ci dessous retourne ce résultat. Il faut mieux appeler la méthode Move 1 fois, que les propriétés Top et Left (deux appels à l'objet). L'appel à la fonction API MoveWindow n'est pas plus avantageux. Disons que sur ce genre de code, si VB sais le faire, dans la plupart des cas, il sera plus rapide qu'un appel à son équivalent API.

Boucle Me.Left = 1500
Me.Top = 1500
Me.Move 1500, 1500 API MoveWindow
100.000 3.420 2.125 4.308

Sylvain Galia (sygale@ifrance.com), a fait de son côté des tests sur le parcours des collections et des classes de type collection. Il en résulte les chiffres suivants :

Type Boucle For Each ... For i = 0 To ...
Collection 10.000 0.01 3.345
Classe Collection 10.000 0.03 8.072

On se rend compte ainsi que le "For Each" est l'instruction idéale pour le parcours d'une collection. Pour vérifier vous même ce dernier test, vous avez la possibilité de récupérer le code.

Le code utilisé pour tous ces tests se trouve ci-dessous. Si vous faites des découvertes intérressantes au niveau des performances, n'hésitez pas à me les communiquer, elles seront placées ici.

' La feuille est simplement composée de 3 boutons et une zone de texte
' cmdTest , pour lancer le test
' cmdCls , pour effacer la feuille
' cmdQuit , pour quitter
' txtTour , pour indiquer le nombre de tour de boucle

Option Explicit
' Déclaration de l'API de timing (en ms)
Private Declare Function GetTickCount Lib "kernel32" () As Long

Private Sub
cmdTest_Click()
' Bouton pour lancer le test
Dim lgDep As Long, lgFin As Long
Dim
lgFor As Long, lgMax As Long
' Quelques variables temporaires à utiliser pour les tests
Dim stTmp As String, stTmp2 As String, stTmp3 As String
Dim
lgTmp As Long, lgTmp2 As Long, lgTmp3 As Long

' Nombre de tours de boucle
lgMax = CLng(txtTour.Text)

' Enregistrement du départ
lgDep = GetTickCount
For lgFor = 0 To lgMax
'
' Ici la première version du code à tester ...
'
Next lgFor
lgFin = GetTickCount
' Affichage du résultat pour la première méthode
Me.Print "Méthode 1 : " & lgFin - lgDep;

lgDep = GetTickCount
For lgFor = 0 To lgMax
'
' Ici la seconde version du code à comparer ...
'
Next lgFor
lgFin = GetTickCount
Me.Print " / Méthode 2 : " & lgFin - lgDep
End Sub

Private Sub
cmdCls_Click()
' Pour effacer la feuille
Me.Cls
End Sub

Private Sub
cmdQuit_Click()
' Pour quitter
Unload Me
End Sub
Visual Basic Research Center - (c) 2000/2002 -  Webmaster : docvb (chez) free (point) fr