VBAコードの実行時間をどのようにテストしますか?


回答:


81

関数が非常に遅い場合を除き、非常に高解像度のタイマーが必要になります。私が知っている最も正確なものはQueryPerformanceCounterです。詳細はグーグルで。以下をクラスにプッシュしてみてくださいCTimer、それを言うと、インスタンスをどこかグローバルにして.StartCounter.TimeElapsed

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

2
私は、このKBの記事で述べたようにオーバーヘッドに追加する(エクセルVBAでこれを実装:support.microsoft.com/kb/172338それは素晴らしい仕事をありがとうございました。。。
ランス・ロバーツ

2
おかげで、これも私にとってうまくいきます。TimeElapsed()結果をミリ秒単位で示します。オーバーヘッドの計算におけるスタッターの影響が完全な精度よりも心配されたため、オーバーヘッドの補正は実装しませんでした。
Justin

2
(管理するコード行で)耳にしたことはたくさんあります。〜10msの精度で対応できる場合、@ Kodakの以下の答えは、1行のコード(GetTickCountkernel32からインポート)で同じことを示します。
BrainSlugs83 2014年

StartCounterAndをどのように使用しますTimeElapsedか?私はCTimer最初にTimerのインスタンスを作成しましたが、サブが開始したWith StartCounter直後に書き込んだところ、それが返ってきました。私は聞かせたとき、それは私に語っただけでオブジェクトが設定されていません。.StartCounter.TimeElapsedInvalid use of property.StartCounter
モニカの革命

Excel 2010の場合:Declare PtrSafe Function stackoverflow.com/questions/21611744/…–
user3226167

48

VBAのタイマー機能は、真夜中から経過した秒数を1/100秒まで提供します。

Dim t as single
t = Timer
'code
MsgBox Timer - t

18
それはうまくいきません-そのような平均を取ることからより多くの解像度を得ることができません。
Andrew Scagnelli、2009年

3
それでも、VBAでパフォーマンスを測定している場合、1/100秒の解像度を得ることは悪くありません。-タイミングコールだけを呼び出すと、数ミリ秒かかる場合があります。呼び出しが速すぎて時間を計測するのにそれほど多くの解像度が必要な場合は、その呼び出しに関するパフォーマンスデータはおそらく必要ありません。
BrainSlugs83 2014年

注:Macでは、タイマーは1秒しか正確ではありません。真夜中の前に開始し、真夜中に終了すると、負の数になる可能性があります
TmTron

32

ストップウォッチのように時間を返そうとしている場合、次のAPIを使用して、システムの起動からの時間をミリ秒単位で返すことができます。

Public Declare Function GetTickCount Lib "kernel32.dll" () As Long
Sub testTimer()
Dim t As Long
t = GetTickCount

For i = 1 To 1000000
a = a + 1
Next

MsgBox GetTickCount - t, , "Milliseconds"
End Sub

http://www.pcreview.co.uk/forums/grab-time-milliseconds-included-vba-t994765.htmlより後(winmm.dllのtimeGetTimeが機能せず、QueryPerformanceCounterが必要なタスクに対して複雑すぎたため)


これは素晴らしい答えです。注:返されるデータの精度はミリ秒単位ですが、カウンターの精度は、MSDN経由で約1/100秒(つまり、10〜16
BrainSlugs83 2014年

うーん、解像度がタイマーと同じである場合、タイマーを使います
コダック

そのPublic Declare Function ...部分は何ですか?私の一番下にコードを追加するとエラーが発生します
モニカの革命

この公開宣言をモジュールの一番上に移動する必要があります
コダック


3
Sub Macro1()
    Dim StartTime As Double
    StartTime = Timer

        ''''''''''''''''''''
            'Your Code'
        ''''''''''''''''''''
    MsgBox "RunTime : " & Format((Timer - StartTime) / 86400, "hh:mm:ss")
End Sub

出力:

実行時間:00:00:02



1

小数点以下2桁の秒:

Dim startTime As Single 'start timer
MsgBox ("run time: " & Format((Timer - startTime) / 1000000, "#,##0.00") & " seconds") 'end timer

秒形式

ミリ秒:

Dim startTime As Single 'start timer
MsgBox ("run time: " & Format((Timer - startTime), "#,##0.00") & " milliseconds") 'end timer

ミリ秒形式

コンマ区切りのミリ秒:

Dim startTime As Single 'start timer
MsgBox ("run time: " & Format((Timer - startTime) * 1000, "#,##0.00") & " milliseconds") 'end timer

カンマ区切りのミリ秒

私のように、秒から小数点以下2桁までにフォーマットされた単純なタイマーを探していた人のために、ここに置いておきます。これらは私が使用したい短くて甘い小さなタイマーです。これらは、サブルーチンまたは関数の最初に1行のコードを取り、最後にもう一度1行のコードを取ります。これらは狂ったように正確であるという意味ではありません。私は通常、1/100秒未満のことは個人的に気にしませんが、ミリ秒タイマーがこれら3の最も正確な実行時間を提供します。真夜中に渡っているときに実行すると、誤った読み取りが行われる可能性があります。まれな例ですが、参考までに。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.