高分辨率计时器/代码运行时间 - >高架?

时间:2014-05-29 17:56:17

标签: excel performance vba excel-vba runtime

我试图使用高分辨率计时器查找我的代码运行时间,我注意到计时器的结果不一致,我想知道为什么会这样。

我找到了这篇文章 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

1 个答案:

答案 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正在使用的功能有关,但可能不是一种推论。