Y at-il du code dans VBA, je peux envelopper une fonction avec qui me permettra de connaître le temps qu'il a fallu pour exécuter, de sorte que je puisse comparer les différents temps de fonctionnement des fonctions?Comment testez-vous le temps de fonctionnement du code VBA?
Répondre
À moins que vos fonctions ne soient très lentes, vous aurez besoin d'une minuterie à très haute résolution. Le plus précis que je connaisse est QueryPerformanceCounter
. Recherche le sur Google pour plus d'informations. Essayez de pousser ce qui suit dans une classe, appelez-le CTimer
dire, alors vous pouvez faire une instance quelque part juste et globale appeler .StartCounter
et .TimeElapsed
Option Explicit
Private Type LARGE_INTEGER
lowpart As Long
highpart As Long
End Type
Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As LARGE_INTEGER) As Long
Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As LARGE_INTEGER) As Long
Private m_CounterStart As LARGE_INTEGER
Private m_CounterEnd As LARGE_INTEGER
Private m_crFrequency As Double
Private Const TWO_32 = 4294967296# ' = 256# * 256# * 256# * 256#
Private Function LI2Double(LI As LARGE_INTEGER) As Double
Dim Low As Double
Low = LI.lowpart
If Low < 0 Then
Low = Low + TWO_32
End If
LI2Double = LI.highpart * TWO_32 + Low
End Function
Private Sub Class_Initialize()
Dim PerfFrequency As LARGE_INTEGER
QueryPerformanceFrequency PerfFrequency
m_crFrequency = LI2Double(PerfFrequency)
End Sub
Public Sub StartCounter()
QueryPerformanceCounter m_CounterStart
End Sub
Property Get TimeElapsed() As Double
Dim crStart As Double
Dim crStop As Double
QueryPerformanceCounter m_CounterEnd
crStart = LI2Double(m_CounterStart)
crStop = LI2Double(m_CounterEnd)
TimeElapsed = 1000# * (crStop - crStart)/m_crFrequency
End Property
Nous avons utilisé une solution basée sur timeGetTime en winmm.dll pour la milliseconde pendant de nombreuses années. Voir http://www.aboutvb.de/kom/artikel/komstopwatch.htm
L'article est en allemand, mais le code dans le téléchargement (une classe VBA enveloppant l'appel de fonction dll) est assez simple à utiliser et à comprendre sans être capable de lire l'article.
La fonction Minuterie dans VBA vous indique le nombre de secondes écoulées depuis minuit à 1/100 de seconde.
Dim t as single
t = Timer
'code
MsgBox Timer - t
Si vous avez besoin d'une plus grande résolution, j'exécuterais simplement la fonction 1,000 fois et diviserais le temps total par 1,000.
Cela ne fonctionnerait pas - vous ne pouvez pas obtenir plus de résolution de prendre la moyenne comme ça. –
Néanmoins, si vous mesurez les performances dans VBA, obtenir une résolution de 1/100ème de seconde n'est pas mauvais. - Invoquer les appels de chronométrage seul pourrait prendre quelques ms. Si l'appel est si rapide que vous avez besoin de beaucoup de résolution pour le chronométrer, vous n'avez probablement pas besoin de données sur les performances de cet appel. – BrainSlugs83
+1 pour l'utilisation de la fonction native. – RubberDuck
Si vous essayez de retourner le temps comme un chronomètre, vous pouvez utiliser l'API suivante qui retourne le temps en millisecondes depuis le démarrage du système:
Public Declare Function GetTickCount Lib "kernel32.dll"() As Long
Sub testTimer()
Dim t As Long
t = GetTickCount
For i = 1 To 1000000
a = a + 1
Next
MsgBox GetTickCount - t, , "Milliseconds"
End Sub
après http://www.pcreview.co.uk/forums/grab-time-milliseconds-included-vba-t994765.html (comme dans timeGetTime winmm.dll n'a pas été travaillant pour moi et QueryPerformanceCounter était trop compliqué pour la tâche nécessaire)
Ceci est une excellente réponse. A noter: la * précision * des données renvoyées est en millisecondes, cependant, le compteur est seulement * précis * à environ 1/100ème de seconde (c'est-à-dire qu'il peut être désactivé de 10 à 16 ms) via MSDN: http : //msdn.microsoft.com/en-us/library/windows/desktop/ms724408 (v = vs.85) .aspx – BrainSlugs83
hmm, si la résolution est la même ici qu'avec le temporisateur alors j'irais avec le temporisateur – Kodak
Qu'est-ce que la partie 'Public Declare Function ...'? Il crée une erreur lors de l'ajout de votre code au bas de la mienne – Marine1
pour newbees, ces liens explique comment faire un profilage automatique de tous les sous-marins que vous souhaitez surveiller de temps:
http://www.nullskull.com/a/1602/profiling-and-optimizing-vba.aspx
http://sites.mcpher.com/share/Home/excelquirks/optimizationlink voir procProfiler.zip dans http://sites.mcpher.com/share/Home/excelquirks/downlable-items
Je dans Excel implémenté VBA (en ajoutant dans les frais généraux, comme mentionné dans ce KB article: http://support.microsoft.com/kb/172338. Ça a bien marché. Merci. –
Merci, cela fonctionne bien pour moi aussi. 'TimeElapsed()' donne le résultat en millisecondes. Je n'ai pas mis en place de compensation pour frais généraux parce que j'étais plus préoccupé par l'effet d'un bégaiement dans le calcul des frais généraux qu'une précision parfaite. – Justin
C'est beaucoup d'overheard (dans les lignes de code à gérer) - si vous pouvez vivre avec une précision de ~ 10ms, la réponse de Kodak ci-dessous donne la même chose dans une ligne de code (importer 'GetTickCount' de kernel32). – BrainSlugs83