【问题标题】:Count the program-steps计算程序步骤
【发布时间】:2013-06-08 13:24:06
【问题描述】:

我有一个带有许多循环的“大型”vba 程序,现在我想计算我的程序在启动它时执行的各个命令的每一步,所以也许我可以找到性能不高的循环。我想要一些已执行的步骤。

现在有人知道它是如何工作的吗?还是在Excel2010中已经存在一些功能?

谢谢。我知道我的英语不是很好。 >.

编辑 06.14.13 现在我把它写在我的模块中

Sub DoStuff()
Dim sw As New Stopwatch
sw.Start
Call pranlesen.plan_gen
sw.Pause
Debug.Print "SomeFunction took " & format(sw.Elapsed * 1000, "0.000000") & " milliseconds"
End Sub

这个类是正确的称为秒表我不知道是什么缺陷。

【问题讨论】:

    标签: performance excel vba loops lag


    【解决方案1】:

    如果您的意思是“计算处理器指令的数量”,那么没有办法做到这一点。但是,您可以非常准确地测量经过的时间。在 VBA 中使用 Windows API 函数QueryPerformanceCounter 构造超精确秒表的详细说明见我的文章Accurate Performance Timers in VBA。下面是 Stopwatch 类的完整代码:

    Option Explicit
    
    Private Declare Function QueryPerformanceCounter Lib "kernel32" ( _
        lpPerformanceCount As UINT64) As Long
    Private Declare Function QueryPerformanceFrequency Lib "kernel32" ( _
        lpFrequency As UINT64) As Long
    
    Private pFrequency As Double
    Private pStartTS As UINT64
    Private pEndTS As UINT64
    Private pElapsed As Double
    Private pRunning As Boolean
    
    Private Type UINT64
        LowPart As Long
        HighPart As Long
    End Type
    
    Private Const BSHIFT_32 = 4294967296# ' 2 ^ 32
    
    Private Function U64Dbl(U64 As UINT64) As Double
        Dim lDbl As Double, hDbl As Double
        lDbl = U64.LowPart
        hDbl = U64.HighPart
        If lDbl < 0 Then lDbl = lDbl + BSHIFT_32
        If hDbl < 0 Then hDbl = hDbl + BSHIFT_32
        U64Dbl = lDbl + BSHIFT_32 * hDbl
    End Function
    
    Private Sub Class_Initialize()
        Dim PerfFrequency As UINT64
        QueryPerformanceFrequency PerfFrequency
        pFrequency = U64Dbl(PerfFrequency)
    End Sub
    
    Public Property Get Elapsed() As Double
        If pRunning Then
            Dim pNow As UINT64
            QueryPerformanceCounter pNow
            Elapsed = pElapsed + (U64Dbl(pNow) - U64Dbl(pStartTS)) / pFrequency
        Else
            Elapsed = pElapsed
        End If
    End Property
    
    Public Sub Start()
        If Not pRunning Then
            QueryPerformanceCounter pStartTS
            pRunning = True
        End If
    End Sub
    
    Public Sub Pause()
        If pRunning Then
            QueryPerformanceCounter pEndTS
            pRunning = False
            pElapsed = pElapsed + (U64Dbl(pEndTS) - U64Dbl(pStartTS)) / pFrequency
        End If
    End Sub
    
    Public Sub Reset()
        pElapsed = 0
        pRunning = False
    End Sub
    
    Public Sub Restart()
        pElapsed = 0
        QueryPerformanceCounter pStartTS
        pRunning = True
    End Sub
    
    Public Property Get Running() As Boolean
       Running = pRunning
    End Property
    

    将上述代码粘贴到新的 Class 模块中,并将模块命名为“Stopwatch”。然后在你的代码中的任何其他地方你都可以做这样的事情:

    Sub DoStuff
        Dim sw As New Stopwatch
        sw.Start
        myResult = SomeFunction(A, B, C)
        sw.Pause
        Debug.Print "SomeFunction took " & Format(sw.Elapsed * 1000, "0.000000") & " milliseconds"
    End Sub
    

    【讨论】:

    • 感谢您的回答,确实非常有用!
    • 感谢您的回答,它可能有用,但我不明白,SomeFunction 是做什么的...?
    • 我应该在那里写我的mainfunction吗?
    • @Synoon "SomeFunction" 什么都不是。它的意思是“把你想要的东西放在这里”。
    • 是的,这很清楚,但我应该把我的主要放在那里,而不是在 DoStuff 上启动 marco
    猜你喜欢
    • 2016-08-27
    • 2017-02-10
    • 2011-04-03
    • 2021-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-22
    相关资源
    最近更新 更多