0

多くのループを含む「大規模な」vba-programm があります。プログラムを開始するときに、プログラムのそれぞれのコマンドが実行する各ステップをカウントしたいので、実際にはパフォーマンスの低いループを見つけることができるかもしれません。いくつかの実行されたステップが必要です。

今、誰かがそれがどのように機能するか知っていますか? それともExcel2010にはすでにそのための関数がいくつか存在しますか?

どうも。私は自分の英語があまり上手でないことを知っています。>.<

Edit 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

クラスはストップウォッチとして正しく呼び出されますが、何が欠陥なのかわかりません。

4

1 に答える 1

2

「プロセッサ命令の数をカウントする」という意味であれば、それを行う方法はありません。ただし、経過時間は非常に正確に測定できます。Windows API 関数QueryPerformanceCounterを使用して VBA で超正確なストップウォッチを作成する方法の詳細については、私の記事「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

上記のコードを新しいクラス モジュールに貼り付け、モジュールに「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
于 2013-06-12T12:46:16.450 に答える