TEMPS D'EXECUTION D'UN BOUT DE CODE (BENCHMARK POUR OPTIMISATION)

Cacophrene Messages postés 251 Date d'inscription lundi 29 mars 2004 Statut Membre Dernière intervention 4 mars 2008 - 12 août 2006 à 07:10
cs_jym Messages postés 115 Date d'inscription lundi 31 décembre 2001 Statut Membre Dernière intervention 15 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.

https://codes-sources.commentcamarche.net/source/39065-temps-d-execution-d-un-bout-de-code-benchmark-pour-optimisation

cs_jym Messages postés 115 Date d'inscription lundi 31 décembre 2001 Statut Membre Dernière intervention 15 avril 2014
17 août 2006 à 17:35
bjr,

moi j'apprécie votre code car il me dépanne bien.

j'ai fait des essais avec l'ocx et c'est pas mal du tout pour ce que je veux faire. la précision me suffit pour améliorer des boucles et des itérations successives. j'avais un code un peu empirique et pas trop structuré. ce genre de test me suffit amplement.

merci à vous.

jym
Cacophrene Messages postés 251 Date d'inscription lundi 29 mars 2004 Statut Membre Dernière intervention 4 mars 2008 1
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 :

'========================================================
'--------------------------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
Cacophrene Messages postés 251 Date d'inscription lundi 29 mars 2004 Statut Membre Dernière intervention 4 mars 2008 1
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
MadM@tt Messages postés 2167 Date d'inscription mardi 11 novembre 2003 Statut Membre Dernière intervention 16 juillet 2009 1
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
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
12 août 2006 à 10:12
Sers toi de cela:
http://www.vbfrance.com/code.aspx?id=18494
et tu liras les ticks cpu pour une vraie mesure fine.
Cacophrene Messages postés 251 Date d'inscription lundi 29 mars 2004 Statut Membre Dernière intervention 4 mars 2008 1
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
Rejoignez-nous