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

标签 performance vba excel 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

最佳答案

链接类不是很好。调用 QueryPerformanceCounter 会产生开销,并且应该首先确定开销,然后用于调整后续调用。这可以解释所有结果都比预期的稍慢,但是它并不能解释第一个慢得多 .无论如何,请参阅 http://support.microsoft.com/kb/172338描述了一种对其进行调整的方法。我目前无法访问我已实现的类(class),因此我无法发布相关部分。

对于与您的特定问题无关但通常与 Windows 上的计时相关的阅读,http://msdn.microsoft.com/en-gb/library/windows/desktop/dn553408%28v=vs.85%29.aspx很有趣。

同时,作为一种解决方法,在 Class_Initialize 中添加一个开始然后停止的调用。

这根本不是一个真正的答案-更多的是扩展评论-因此,如果我找到确凿的理由,我将对其进行编辑;)

向那些赞成的人重申:我无法解释 OP 查询结果的原因。我假设这与 VBA 解释器(即接近 JIT'er)有关,但我无法证明任何一种方式。我上面的评论与 OP 正在使用的功能有关,但可能是不合理的。

关于performance - 高分辨率计时器/代码运行时间-> 开销?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23939806/

相关文章:

excel - 如果列包含日期,则 IF 语句计算日期之间的天数

java - AWS Lambdas 中对 JDK 11 的支持是否会带来任何性能改进?特别是关于冷启动?

mysql - 在 Access VBA 中循环 Access strSQL 中的日期

c# - 监控 C# 方法性能的工具

excel - 在 Excel 中将单元格的内容保存到不带引号的 csv

vba - 相交命令因工作表范围不同而失败

Excel VBA 使用 .Cells 定义 .Range

excel - 检查工作表是否存在,如果不存在则创建 -VBA

c++ - 有哪些小型、快速和轻量级的开源应用程序(µTorrent 式)?

Javascript显示更多/显示更少具有速度效果