Net 2.0 : StopWatch, ou le temps qui passeDate de publication : 30/01/2006
Par
Ronald VASSEUR (autres articles)

Lorsque vous réalisez des applications, vous avez souvent plusieurs
voies possibles pour effectuer une opération, au-delà des aspects
de sécurité et de fiabilité, l'aspect de la performance est à prendre
en compte. La manière la plus évidente de mesurer la performance de
votre code est en fait de regarder son temps d'exécution...
Introduction
1. Présentation de la classe StopWatch
1.1. Les méthodes
1.2. Les propriétés
2. Mesurer le temps d'exécution d'une méthode
3. Mesurer le temps d'exécution cumulé de plusieurs méthodes
4. Une mini application exemple
Conclusion
C. Ressources
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.000001 seconde). Voyons de plus
près et sans plus tarder cette classe.
 .Net 2.0
1. 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 serai 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 :
1.1. 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 utiliser 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. |
1.2. 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…
2. 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 pour C# | using System.Diagnostics |
| Imports pour Visual Basic .Net | 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 içi de démontrer comment mesurer un temps d'exécution facilement.
| Fonctions de test |
Private Function test1() As Boolean
Dim i As Integer
Dim strB As New StringBuilder
For i = 0 To 20000
strB.Append("d")
Next
strB.ToString()
Return True
End Function
Private Function test2() As Boolean
Dim i As Integer
Dim str As String = Nothing
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 soit
terminée.
| Mesure du temps d'exécution | Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Dim monSWtest1 As New Stopwatch
monSWtest1.Start()
test1()
monSWtest1.Stop()
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 puissez 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 comppilateur JIT, ce n'est donc
qu'au deuxième appel que la "performance réelle" du code est mesuré.
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é continue.
|
3. 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 simplement 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 ! :)
| Code permettant d'effectuer une mesure d'exécutions cumulées | Private Sub Button3_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button3.Click
Dim monSWcumul As New Stopwatch
monSWcumul.Start()
test2()
monSWcumul.Stop()
monSWcumul.Start()
test2()
monSWcumul.Stop()
Label3.Text = monSWcumul.ElapsedMilliseconds.ToString & " milliseconde(s)"
End Sub |
4. Une mini application exemple
Pour illustrer tout cela et avoir un exemple fonctionnel, j'ai réalisé
une mini-application 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 à rien de 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 mini-application :
 Application exemple.
Comme vous le voyez cette application permet de comparer le temps
pris par une concaténation de 20000 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 mini-application 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 à 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.
C. Ressources
Un très grand merci à Freegreg pour la relecture de cet article.
 
|