¿Hay un 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?
¿Hay un 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?
Respuestas:
A menos que sus funciones sean muy lentas, necesitará un temporizador de muy alta resolución. El más preciso que conozco es QueryPerformanceCounter
. Google para obtener más información. Intente insertar lo siguiente en una clase, llámelo CTimer
digamos, luego puede hacer una instancia en algún lugar global y simplemente llamar .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
TimeElapsed()
da el resultado en milisegundos. No implementé ninguna compensación de gastos generales porque estaba más preocupado por el efecto de un tartamudeo en el cálculo de gastos generales que la precisión perfecta.
GetTickCount
desde kernel32).
StartCounter
And TimeElapsed
? Hice una instancia de Timer de CTimer
al principio y With StartCounter
escribí .StartCounter
después de que mi sub comenzara y .TimeElapsed
me respondió Invalid use of property
. Cuando lo dejo .StartCounter
solo, me dice que un objeto no está configurado.
Declare PtrSafe Function
stackoverflow.com/questions/21611744/…
La función de temporizador en VBA le da el número de segundos transcurridos desde la medianoche, a 1/100 de segundo.
Dim t as single
t = Timer
'code
MsgBox Timer - t
Si está tratando de devolver la hora como un cronómetro, puede usar la siguiente API que devuelve la hora 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 (ya que timeGetTime en winmm.dll no funcionaba para mí y QueryPerformanceCounter era demasiado complicado para la tarea necesaria)
Public Declare Function ...
parte Crea un error al agregar su código en la parte inferior del mío
Para los principiantes, estos enlaces explican cómo hacer un perfil automático de todos los subs que desea monitorear 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
Sub Macro1()
Dim StartTime As Double
StartTime = Timer
''''''''''''''''''''
'Your Code'
''''''''''''''''''''
MsgBox "RunTime : " & Format((Timer - StartTime) / 86400, "hh:mm:ss")
End Sub
Salida:
Tiempo de ejecución: 00:00:02
Hemos utilizado una solución basada en timeGetTime en winmm.dll para 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 de 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.
Segundos con 2 espacios decimales:
Dim startTime As Single 'start timer
MsgBox ("run time: " & Format((Timer - startTime) / 1000000, "#,##0.00") & " seconds") 'end timer
Milisegundos:
Dim startTime As Single 'start timer
MsgBox ("run time: " & Format((Timer - startTime), "#,##0.00") & " milliseconds") 'end timer
Milisegundos con separador de coma:
Dim startTime As Single 'start timer
MsgBox ("run time: " & Format((Timer - startTime) * 1000, "#,##0.00") & " milliseconds") 'end timer
Solo dejo esto aquí para cualquiera que esté buscando un temporizador simple formateado con segundos a 2 espacios decimales como yo. Estos son pequeños temporizadores cortos y dulces que me gusta usar. Solo ocupan una línea de código al comienzo de la función o sub y una línea de código nuevamente al final. Estos no están destinados a ser muy precisos, por lo general no me importa nada menos de 1/100 de segundo personalmente, pero el temporizador de milisegundos le dará el tiempo de ejecución más preciso de estos 3. También le he leído puede obtener la lectura incorrecta si se ejecuta mientras cruza la medianoche, un caso raro pero solo para su información.