我试图使用高分辨率计时器查找我的代码运行时间,我注意到计时器的结果不一致,我想知道为什么会这样。
我找到了这篇文章
How do you test running time of VBA code?
并且已经实现了最佳答案,我尝试使用它来查找几个函数的运行时间,并注意到结果发生了相当大的变化。
为了查看这是否是计时器的故障,我做了一个我刚刚启动并停止计时器的功能。
Public Sub test_ctimer()
Dim results(0 To 4) As Double
Dim t As CTimer: Set t = New CTimer
Dim i As Integer
'Removes msg box overhead
MsgBox "about to start"
For i = 0 To 4
t.StartCounter
results(i) = t.TimeElapsed
Next i
For i = 0 To 4
MsgBox results(i)
Next i
End Sub
第一次测量比以下任何测量都花费更多的时间(大约1个数量级)。有人知道为什么吗?
以下是来自How do you test running time of VBA code?
的ctimer代码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
答案 0 :(得分:1)
链接的课程不是很好。调用QueryPerformanceCounter会产生开销,应首先确定开销,然后用于调整后续调用。 这可以解释所有结果比预期慢一些,然而它并没有解释第一个结果慢得多。无论如何,请参阅http://support.microsoft.com/kb/172338描述了一种调整方法。我实施的课程目前无法访问,因此我无法发布相关部分。
另外,对于与您的特定问题无关且与Windows上的Timings相关的阅读,http://msdn.microsoft.com/en-gb/library/windows/desktop/dn553408%28v=vs.85%29.aspx很有意思。
在此期间作为解决方法,添加一个调用以启动然后在Class_Initialize中停止。
这根本不是一个答案 - 更多的是扩展评论 - 所以如果我找到一个确凿的理由,我会编辑它;)
重申那些支持者:我无法解释OP查询结果的原因。我假设这是与VBA解释器(即接近JIT'er)有关,但我不能证明任何一种方式。我上面的评论与OP正在使用的功能有关,但可能不是一种推论。