TEMPS D'EXECUTION D'UN BOUT DE CODE (BENCHMARK POUR OPTIMISATION)
Cacophrene
Messages postés251Date d'inscriptionlundi 29 mars 2004StatutMembreDernière intervention 4 mars 2008
-
12 août 2006 à 07:10
cs_jym
Messages postés115Date d'inscriptionlundi 31 décembre 2001StatutMembreDernière intervention15 avril 2014
-
17 août 2006 à 17:35
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
Cacophrene
Messages postés251Date d'inscriptionlundi 29 mars 2004StatutMembreDernière intervention 4 mars 20081 12 août 2006 à 07:10
Salut !
Voici deux suggestions :
1- GetTickCount donne des mesures en millisecondes (pas très précises). Pour un benchmark plus précis, surtout pour comparer des opérations rapides (je pense par exemple à deux petites boucles équivalentes For To et For Each), il peut être préférable d'utiliser QueryPerformanceCounter.
2- Vu que les mesures dépendent beaucoup, sous Windows, de l'état du système au moment de la mesure, pourquoi pas refaire le test plusieurs fois, puis calculer une moyenne qui a toutes les chances d'être assez proche de la réalité ?
Cordialement,
Cacophrène
BruNews
Messages postés21041Date d'inscriptionjeudi 23 janvier 2003StatutModérateurDernière intervention21 août 201917 12 août 2006 à 10:12
MadM@tt
Messages postés2167Date d'inscriptionmardi 11 novembre 2003StatutMembreDernière intervention16 juillet 20091 12 août 2006 à 14:20
Ok c'est fait, regardez la capture pour voir les modifications.
Enfin cette modif sera beaucoup plus utile pour l'ocx, car avec l'ocx on execute qu'une fois le code à mesurer donc il faut un compteur très précis.
Par contre, en ce qui concerne le fait de réaliser le test plusieurs fois, je ne vois pas la différence entre augmenter le nombre d'itération ?? Plutot que de réaliser 10 fois le test, par exemple, j'execute 10000 fois la fonction au lieu de 1000, et je décale la virgule.
Enfin si vraiment il y en a besoin je le rajoute ;)
Merci à vous 2
Cacophrene
Messages postés251Date d'inscriptionlundi 29 mars 2004StatutMembreDernière intervention 4 mars 20081 12 août 2006 à 15:43
Salut !
Oulà... Laisse tomber la deuxième suggestion. Ce que j'ai écrit ce matin (message du 12/08/2006 07:10:47) ne veut rien dire.
Cordialement,
Cacophrène
Cacophrene
Messages postés251Date d'inscriptionlundi 29 mars 2004StatutMembreDernière intervention 4 mars 20081 13 août 2006 à 10:05
Salut !
Si on considère une feuille avec 4 OptionButton sous forme d'un groupe de contrôle pour indiquer les unités disponibles (Item 0 -> secondes ; Item 1 -> millisecondes...), on pourrait par exemple obtenir (dans un module) assez grossièrement :
'Type grand entier.
Private Type LARGE_INTEGER
LowPart As Long
HighPart As Long
End Type
'Evaluer le temps d'exécution d'un programme
Private Declare Function QueryPerformanceCounter _
Lib "kernel32" ( lpPerformanceCount As LARGE_INTEGER) _
As Long
'Fréquence du compteur de Windows.
Private Declare Function QueryPerformanceFrequency Lib _
"kernel32" (lpFrequency As LARGE_INTEGER) As Long
'Temps initial (au lancement du chronomètre)
Dim SwitchOn As LARGE_INTEGER
'Temps final (à l'arrêt du chronomètre)
Dim SwitchOff As LARGE_INTEGER
'Fréquence du compteur de Windows
Dim Frequency As LARGE_INTEGER
'--------------------------FONCTIONS
'Temps mis pour exécuter une fonction Test.
Private Function GetTime() As String
Dim dCoeff As Double, sUnit As String
Select Case SelectedItem()
Case 0 'secondes
sUnit = " s"
dCoeff = 1
Case 1 'millisecondes
sUnit = " ms"
dCoeff = 10 ^ 3
Case 2 'microsecondes
sUnit = " µs"
dCoeff = 10 ^ 6
Case 3 'nanosecondes
sUnit = " ns"
dCoeff = 10 ^ 9
End Select
GetTime = CStr(dCoeff * (CDbl(SwitchOff.LowPart) _
- CDbl(SwitchOn.LowPart)) / CDbl(Frequency.LowPart)) _
& sUnit
End Function
'Calcule le résultat d'une fonction Test (quelconque)
Private Function GetResult() As Variant
Call QueryPerformanceFrequency(Frequency)
Call QueryPerformanceCounter(SwitchOn)
GetResult = Test
Call QueryPerformanceCounter(SwitchOff)
End Function
'Dans un groupe de contrôles, choix de l'OptionButton
'sélectionné
Private Function SelectedItem() As Integer
Dim k As Integer
SelectedItem = -1
Do
If OPT(k).Value Then SelectedItem = k
k = k + 1
Loop Until (SelectedItem > -1) Or (k > OPT.UBound)
End Function
12 août 2006 à 07:10
Voici deux suggestions :
1- GetTickCount donne des mesures en millisecondes (pas très précises). Pour un benchmark plus précis, surtout pour comparer des opérations rapides (je pense par exemple à deux petites boucles équivalentes For To et For Each), il peut être préférable d'utiliser QueryPerformanceCounter.
2- Vu que les mesures dépendent beaucoup, sous Windows, de l'état du système au moment de la mesure, pourquoi pas refaire le test plusieurs fois, puis calculer une moyenne qui a toutes les chances d'être assez proche de la réalité ?
Cordialement,
Cacophrène
12 août 2006 à 10:12
http://www.vbfrance.com/code.aspx?id=18494
et tu liras les ticks cpu pour une vraie mesure fine.
12 août 2006 à 14:20
Enfin cette modif sera beaucoup plus utile pour l'ocx, car avec l'ocx on execute qu'une fois le code à mesurer donc il faut un compteur très précis.
Par contre, en ce qui concerne le fait de réaliser le test plusieurs fois, je ne vois pas la différence entre augmenter le nombre d'itération ?? Plutot que de réaliser 10 fois le test, par exemple, j'execute 10000 fois la fonction au lieu de 1000, et je décale la virgule.
Enfin si vraiment il y en a besoin je le rajoute ;)
Merci à vous 2
12 août 2006 à 15:43
Oulà... Laisse tomber la deuxième suggestion. Ce que j'ai écrit ce matin (message du 12/08/2006 07:10:47) ne veut rien dire.
Cordialement,
Cacophrène
13 août 2006 à 10:05
Si on considère une feuille avec 4 OptionButton sous forme d'un groupe de contrôle pour indiquer les unités disponibles (Item 0 -> secondes ; Item 1 -> millisecondes...), on pourrait par exemple obtenir (dans un module) assez grossièrement :
'========================================================
'--------------------------DECLARATIONS
'Type grand entier.
Private Type LARGE_INTEGER
LowPart As Long
HighPart As Long
End Type
'Evaluer le temps d'exécution d'un programme
Private Declare Function QueryPerformanceCounter _
Lib "kernel32" ( lpPerformanceCount As LARGE_INTEGER) _
As Long
'Fréquence du compteur de Windows.
Private Declare Function QueryPerformanceFrequency Lib _
"kernel32" (lpFrequency As LARGE_INTEGER) As Long
'Temps initial (au lancement du chronomètre)
Dim SwitchOn As LARGE_INTEGER
'Temps final (à l'arrêt du chronomètre)
Dim SwitchOff As LARGE_INTEGER
'Fréquence du compteur de Windows
Dim Frequency As LARGE_INTEGER
'--------------------------FONCTIONS
'Temps mis pour exécuter une fonction Test.
Private Function GetTime() As String
Dim dCoeff As Double, sUnit As String
Select Case SelectedItem()
Case 0 'secondes
sUnit = " s"
dCoeff = 1
Case 1 'millisecondes
sUnit = " ms"
dCoeff = 10 ^ 3
Case 2 'microsecondes
sUnit = " µs"
dCoeff = 10 ^ 6
Case 3 'nanosecondes
sUnit = " ns"
dCoeff = 10 ^ 9
End Select
GetTime = CStr(dCoeff * (CDbl(SwitchOff.LowPart) _
- CDbl(SwitchOn.LowPart)) / CDbl(Frequency.LowPart)) _
& sUnit
End Function
'Calcule le résultat d'une fonction Test (quelconque)
Private Function GetResult() As Variant
Call QueryPerformanceFrequency(Frequency)
Call QueryPerformanceCounter(SwitchOn)
GetResult = Test
Call QueryPerformanceCounter(SwitchOff)
End Function
'Dans un groupe de contrôles, choix de l'OptionButton
'sélectionné
Private Function SelectedItem() As Integer
Dim k As Integer
SelectedItem = -1
Do
If OPT(k).Value Then SelectedItem = k
k = k + 1
Loop Until (SelectedItem > -1) Or (k > OPT.UBound)
End Function
'========================================================
Comme ça on peut choisir l'unité de mesure la plus appropriée au type de calcul à effectuer.
Cordialement,
Cacophrène