Introduction▲
Avant le Framework .Net en version 2.0, il pouvait être assez compliqué de mesurer précisément un temps d'exécution. Avec .Net, tout ceci est désormais terminé, en effet, une nouvelle classe StopWatch propose de nous rendre ce service avec une précision remarquable, de l'ordre de la microseconde (0,000 001 seconde). Voyons de plus près et sans plus tarder cette classe.
I. Présentation de la classe StopWatch▲
Le Framework .Net 2.0, dans sa multitude de nouvelles classes, nous apporte ce que l'on pourrait considérer comme une petite classe, mais il faut bien le reconnaître d'une très grande utilité pour les développeurs que nous sommes. La classe StopWatch, c'est son nom, faisant partie du namespace System.Diagnostics, nous offre des méthodes permettant de mesurer très précisément (de l'ordre de la microseconde) le temps d'exécution de notre code, et cela sans effort aucun, je serais tenté de dire trivialement « plus simple que cela tu meurs ». Voici les méthodes et les propriétés principales que vous devez connaître.
I-A. Les méthodes▲
Nom |
Description |
---|---|
Start() |
démarre le chronomètre qui mesure l'intervalle de temps entre le « Start » et le « Stop ». Le Start() peut aussi être utilisé pour relancer un chronomètre qui a déjà été stoppé par un Stop() dans le cas de mesures cumulées. |
Stop() |
arrête le chronomètre qui mesure l'intervalle depuis le Start(). |
Reset() |
remise à zéro du temps déjà écoulé sur le chronomètre. |
StartNew() |
instancie une nouvelle instance de l'objet StopWatch avec la propriété Elapsed à 0. |
I-B. Les propriétés▲
Nom |
Description |
---|---|
Elapsed |
Temps total (sous la forme d'un TimeSpan) écoulé mesuré par l'instance courante de l'objet StopWatch. |
ElapsedMilliseconds |
Temps total écoulé en millisecondes mesuré par l'instance courante l'objet StopWatch. |
ElapsedTicks |
Nombre total de « timer ticks » mesurés par l'instance courante l'objet StopWatch. |
IsRunning |
Booléen qui détermine si l'instance courante de StopWatch est active, c'est-à-dire si elle est en train de mesurer un intervalle. |
Après avoir vu les méthodes et propriétés principales de StopWatch, étudions un petit exemple nous permettant de mesurer le temps d'exécution d'une méthode toute simple…
II. Mesurer le temps d'exécution d'une méthode▲
Voici un exemple simple qui montre comment mesurer le temps d'exécution d'une méthode, pour cela il va nous falloir utiliser une instance de StopWatch, ses deux méthodes Start() et Stop() et sa propriété ElapsedMilliseconds qui va nous donner un résultat en millisecondes, choix qui est ici pertinent, puisque le résultat attendu sera de quelques millisecondes. Si vous souhaitiez mesurer des temps d'exécution plus longs pour des raisons concrètes de lisibilité, il serait peut-être plus judicieux d'utiliser par exemple la propriété Elapsed qui vous fournit un TimeSpan, et non pas un entier (Long) comme ElapsedMillisecondes.
Remarque : la classe StopWatch appartient au namespace System. Diagnostics, il vous faut donc penser à le signaler dans l'entête de votre classe, comme vous pouvez le voir ci-dessous.
using
System.
Diagnostics
Imports
System.Diagnostics
Voici les deux fonctions dont le temps d'exécution va être mesuré par StopWatch, j'ai volontairement choisi des exemples simplistes, le but étant ici de démontrer comment mesurer un temps d'exécution facilement.
' Fonction de test qui concatène 20000 caractères grâce à la classe StringBuilder
Private
Function
test1
(
) As
Boolean
Dim
i As
Integer
Dim
strB As
New
StringBuilder
' Boucle de concaténation de caractères
For
i =
0
To
20000
strB.Append
(
"d"
)
Next
strB.ToString
(
)
Return
True
End
Function
' Fonction de test qui concatène 20000 caractères grâce à la classe String
Private
Function
test2
(
) As
Boolean
Dim
i As
Integer
Dim
str As
String
=
Nothing
' Boucle de concaténation de caractères
For
i =
0
To
20000
str &=
"d"
Next
Return
True
End
Function
Voici maintenant le code du bouton permettant d'instancier l'objet StopWatch, puis d'effectuer la mesure du temps d'exécution, ici je déclenche le chrono juste avant l'appel de la fonction, et l'arrête immédiatement après qu'elle s'est terminée.
Private
Sub
Button1_Click
(
ByVal
sender As
System.Object
, _
ByVal
e As
System.EventArgs
) Handles
Button1.Click
' Instanciation d'un objet StopWatch
Dim
monSWtest1 As
New
Stopwatch
' Déclenchement du "chronomètre"
monSWtest1.Start
(
)
' Lancement de la fonction de test
test1
(
)
' Arrêt du "chronomètre"
monSWtest1.Stop
(
)
' Récupération et affichage du temps écoulé
Label1.Text
=
monSWtest1.ElapsedMilliseconds.ToString
&
" milliseconde(s)"
End
Sub
De par la nature même de la technologie .Net, il vous faut exécuter au moins une fois la mesure pour que par la suite vous puissiez obtenir un résultat fiable, en effet, lors du premier appel d'une méthode le code MSIL de l'assembly est compilé par le compilateur JIT, ce n'est donc qu'au deuxième appel que la « performance réelle » du code est mesurée. De plus, mais comme pour tout test qui se respecte, pour avoir des résultats fiables il ne faut pas hésiter à multiplier les essais pour se voir dégager une valeur moyenne, en effet une machine ne présente pas un taux de charge et de disponibilité continu.
III. Mesurer le temps d'exécution cumulé de plusieurs méthodes▲
Il est possible de mesurer l'exécution cumulée de plusieurs méthodes, pour cela il suffit d'arrêter le « chronomètre » puis de le relancer pour la méthode suivante, sans bien entendu le réinitialiser entre-temps. Vous pouvez ainsi réaliser des mesures de manière aisée et souple, et même si cela peut apparaître « gadget » au premier abord, à l'usage cela devient un outil 'inutile' donc totalement indispensable ! :)
Private
Sub
Button3_Click
(
ByVal
sender As
System.Object
, _
ByVal
e As
System.EventArgs
) Handles
Button3.Click
' Instanciation d'un objet StopWatch
Dim
monSWcumul As
New
Stopwatch
' Déclenchement du "chronomètre"
monSWcumul.Start
(
)
' Lancement de la fonction de test
test2
(
)
' Arrêt du "chronomètre"
monSWcumul.Stop
(
)
' Le chronomètre est relancé et reprend là où il avait été arrêté
monSWcumul.Start
(
)
' Lancement pour la seconde fois de la fonction de test
test2
(
)
' Arrêt du "chronomètre"
monSWcumul.Stop
(
)
' Récupération et affichage du temps écoulé
Label3.Text
=
monSWcumul.ElapsedMilliseconds.ToString
&
" milliseconde(s)"
End
Sub
IV. Une miniapplication exemple▲
Pour illustrer tout cela et avoir un exemple fonctionnel, j'ai réalisé une miniapplication qui permet de mesurer le temps d'exécution de méthodes, dans différentes configurations comme nous l'avons vu au long de cet article. Vous verrez qu'il n'y a rien d'extraordinaire dans ce programme, juste de quoi démontrer le principe de base.
Remarque : j'ai réalisé cette application en Visual Basic .Net, mais vous pouvez très facilement convertir le code en C# grâce au convertisseur de Developpez.com, ou même à la main, car il n'y a pas de code complexe.
Voici une capture d'écran de cette miniapplication :
Comme vous le voyez cette application permet de comparer le temps pris par une concaténation de 20 000 caractères, et cela avec une String classique, et avec un StringBuilder, qui vous vous en doutez déjà sera bien plus performant.
L'exécutable ainsi que les sources (Solution Visual Studio 2005) de cette miniapplication sont disponibles en téléchargement dans la rubrique « Ressources » de cet article.
Conclusion▲
Vous avez pu voir, par le biais de cet article, qu'il n'y a rien de révolutionnaire, mais tout de même, cette classe StopWatch est quand même une nouveauté très intéressante de la version 2.0 du Framework .Net, en effet, lors de développement, on peut être amené à vouloir estimer la performance de son code ou encore choisir entre plusieurs possibilités. Avant pour mesurer un temps d'exécution, il fallait soit créer soit même, soit utiliser le peu de solutions existantes dans le Framework, qui de plus, étaient trop imprécises et rigides. N'oubliez pas qu'ici la précision est de l'ordre de la microseconde.
Cette petite classe trouvera donc tout un tas d'applications différentes, celle qui me semble personnellement la plus intéressante est la mesure du temps d'exécution de méthodes dans une optique d'évaluation des performances, cependant je suis sûr que chacun d'entre vous aura une très bonne raison d'utiliser cette nouvelle classe. Merci d'avoir pris le temps de lire tout ceci, et rendez-vous bientôt pour un nouvel article.
V. Ressources▲
- Projet Visual Studio 2005 (VB.Net) (98 Ko) : Cliquez ici
- Miniapplication de mesure de temps d'exécution (7 Ko) : Cliquez ici
- Le namespace System.Diagnostics : Cliquez ici
- La classe StopWatch : Cliquez ici
- La classe StringBuilder : Cliquez ici
Un très grand merci à Freegreg pour la relecture de cet article.