optimization - refrescar - ¿Cómo se prueba el tiempo de ejecución del código VBA?
trucos macros (5)
Hemos utilizado una solución basada en timeGetTime en winmm.dll con una precisión de milisegundos durante muchos años. Ver http://www.aboutvb.de/kom/artikel/komstopwatch.htm
El artículo está en alemán, pero el código en la descarga (una clase de VBA que envuelve la llamada a la función dll) es lo suficientemente simple de usar y comprender sin poder leer el artículo.
¿Hay algún código en VBA con el que pueda ajustar una función que me permita saber el tiempo que tardó en ejecutarse, de modo que pueda comparar los diferentes tiempos de ejecución de las funciones?
La función del temporizador en VBA le da la cantidad de segundos transcurridos desde la medianoche hasta 1/100 de segundo.
Dim t as single
t = Timer
''code
MsgBox Timer - t
Si necesita una resolución mayor, simplemente ejecutaría la función 1,000 veces y dividiría el tiempo total por 1,000.
Para los recién nacidos, estos enlaces explican cómo hacer un perfil automático de todos los subs que desea monitorizar en el tiempo:
http://www.nullskull.com/a/1602/profiling-and-optimizing-vba.aspx
http://sites.mcpher.com/share/Home/excelquirks/optimizationlink ver procProfiler.zip en http://sites.mcpher.com/share/Home/excelquirks/downlable-items
Si intenta devolver el tiempo como un cronómetro, puede usar la siguiente API que devuelve el tiempo en milisegundos desde el inicio del sistema:
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
después de http://www.pcreview.co.uk/forums/grab-time-milliseconds-included-vba-t994765.html (como timeGetTime en winmm.dll no funcionaba para mí y QueryPerformanceCounter era demasiado complicado para la tarea necesaria)
A menos que tus funciones sean muy lentas, necesitarás un temporizador de muy alta resolución. El más preciso que conozco es QueryPerformanceCounter
. Google para obtener más información. Intenta CTimer
lo siguiente en una clase, llámalo CTimer
decir, luego puedes crear una instancia en algún lugar global y simplemente llamar a .StartCounter
y .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