Как вы тестируете время выполнения кода VBA?

80

Есть ли код в VBA, я могу обернуть функцию, которая позволит мне узнать время, которое требуется для запуска, чтобы я мог сравнивать разные времена работы функций?

Теги:
optimization
performance
testing
profiling

5 ответов

71
Лучший ответ

Если ваши функции не очень медленные, вам понадобится таймер с очень высоким разрешением. Самый точный, который я знаю, QueryPerformanceCounter. Google для получения дополнительной информации. Попробуйте нажать следующее в классе, назовите его CTimer say, тогда вы можете сделать экземпляр где-то глобальным и просто вызвать .StartCounter и .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
  • 2
    Я реализовал это в Excel VBA (добавив в заголовок Overhead, как упомянуто в этой статье базы знаний : support.microsoft.com/kb/172338 . Он работал отлично. Спасибо.
  • 1
    Спасибо, это тоже хорошо работает для меня. TimeElapsed() дает результат в миллисекундах. Я не использовал компенсацию накладных расходов, потому что меня больше беспокоило влияние заикания в расчете накладных расходов, чем идеальная точность.
Показать ещё 3 комментария
42

Функция таймера в VBA дает вам количество секунд, прошедших с полуночи, до 1/100 секунды.

Dim t as single
t = Timer
'code
MsgBox Timer - t

Если вам нужно большее разрешение, я просто буду запускать функцию 1000 раз и делить общее время на 1000.

  • 17
    Это не сработает - вы не сможете получить больше разрешения, если будете брать среднее.
  • 2
    Тем не менее, если вы измеряете производительность в VBA, получить разрешение на 1/100 секунды не плохо. - Одновременный вызов времени может занять пару мс. Если вызов настолько быстрый, что вам нужно такое разрешение, чтобы рассчитать время, вам, вероятно, не нужны данные о производительности этого вызова.
Показать ещё 3 комментария
28

Если вы пытаетесь вернуть время, как секундомер, вы можете использовать следующий API, который возвращает время в миллисекундах с момента запуска системы:

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

после http://www.pcreview.co.uk/forums/grab-time-milliseconds-included-vba-t994765.html (поскольку timeGetTime в winmm.dll не работал у меня, и QueryPerformanceCounter был слишком сложным для требуемой задачи)

  • 0
    Это отличный ответ. Следует отметить: точность возвращаемых данных указывается в миллисекундах, однако счетчик с точностью до 1/100 секунды (то есть может быть отключен на 10–16 мс) через MSDN: msdn.microsoft.com / EN-US / библиотека / окна / настольные / ...
  • 0
    хм, если разрешение здесь такое же, как с таймером, то я бы пошел с таймером
Показать ещё 2 комментария
4

Для новичков эти ссылки объясняют, как выполнять автоматическое профилирование всех подсайтов, которые вы хотите отслеживать во времени:

http://www.nullskull.com/a/1602/profiling-and-optimizing-vba.aspx

http://sites.mcpher.com/share/Home/excelquirks/optimizationlink см. procProfiler.zip в http://sites.mcpher.com/share/Home/excelquirks/downlable-items

2

Мы использовали решение на основе timeGetTime в winmm.dll для миллисекундной точности в течение многих лет. См. http://www.aboutvb.de/kom/artikel/komstopwatch.htm

Статья находится на немецком языке, но код в загрузке (класс VBA, завершающий вызов функции dll) достаточно прост, чтобы использовать и понимать, не имея возможности прочитать статью.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню