2015-07-13 97 views
1

我想通過循環每個數據類型(整數,雙精度,十進制和變量)的一百萬個隨機數後測試數據類型之間的執行時間差異。我從微軟開發者網站獲取了這段代碼。我使用Excel 2010中VBA QueryPerformanceCounter不工作

這裏是代碼:

Option Explicit 

    Sub Function1() 

    Module Module1 

    Declare Function QueryPerformanceCounter Lib "Kernel32" (ByRef X As Long) As Short 
    Declare Function QueryPerformanceFrequency Lib "Kernel32" (ByRef X As Long) As Short 

     Dim Ctr1, Ctr2, Freq As Long 
     Dim Acc, I As Integer 

     ' Times 100 increment operations by using QueryPerformanceCounter. 

     If QueryPerformanceCounter(Ctr1) Then ' Begin timing. 
      For I = 1 To 100     ' Code is being timed. 
       Acc += 1 
      Next 
      QueryPerformanceCounter (Ctr2)  ' Finish timing. 
      Console.WriteLine ("Start Value: " & Ctr1) 
      Console.WriteLine ("End Value: " & Ctr2) 
      QueryPerformanceFrequency (Freq) 
      Console.WriteLine ("QueryPerformanceCounter minimum resolution: 1/" & Freq & " seconds.") 
      Console.WriteLine ("100 Increment time: " & (Ctr2 - Ctr1)/Freq & " seconds.") 
     Else 
      Console.WriteLine ("High-resolution counter not supported.") 
     End If 
     ' 
     ' Keep console window open. 
     ' 
     Console.WriteLine() 
     Console.Write ("Press ENTER to finish ... ") 
     Console.Read() 

    End Module 

    End Sub 

    Sub Function1_Int_RandNumCounter() 

    Dim Int_RandNum_X As Integer 
    Dim Int_RandNum_Y As Integer 
    Dim Count As Integer 

    For Count = 1 To Count = 1000000 
     Int_RandNum_X = Rnd(Now) ' Get rnd vals based on Now, built-in VBA property 
     Int_RandNum_Y = Rnd(Now) 
    Next Count 

    ' Call Function1_Dbl_RandNumCounter 

End Sub 

Sub Function1_Dbl_RandNumCounter() 

Dim Dbl_RandNum_X As Double, Dbl_RandNum_Y As Double, Count As Double 

    For Count = 1 To Count = 1000000 
     Dbl_RandNum_X = Rnd(Now) ' Get rnd vals based on Now, built-in VBA property 
     Dbl_RandNum_Y = Rnd(Now) 
    Next Count 

    Call Function1_Var_RandNumCounter 
End Sub 
Sub Function1_Var_RandNumCounter() 

Dim Var_RandNum_X, Var_RandNum_Y, Count As Variant 

    For Count = 1 To Count = 1000000 
     Var_RandNum_X = Rnd(Now) ' Get rnd vals based on Now, built-in VBA property 
     Var_RandNum_Y = Rnd(Now) 
    Next Count 

    Call Function1_Dec_RandNumCounter 

End Sub 
Sub Function1_Dec_RandNumCounter() 

Dim Count, Var_RandNum_X, dec_RandNum_X, Var_RandNum_Y, dec_RandNum_Y 

dec_RandNum_X = CDec(Var_RandNum_X) 
dec_RandNum_Y = CDec(Var_RandNum_Y) ' convert these vals to decimals 

    For Count = 1 To Count = 1000000 
     dec_RandNum_X = Rnd(Now) ' Get rnd vals based on Now, built-in VBA property 
     dec_RandNum_Y = Rnd(Now) 
    Next Count 

    Call Function2_BarGraph 

End Sub 
Sub Function2_BarGraph() 
' Put all of these vals in a 2D bar graph 
End Sub 

此代碼給了我的錯誤,如:

Compile error:

Only comments may appear after End Sub, End Function, or End Property

編輯:這裏是代碼,它具有的改進版沒有編譯錯誤,但我不知道如何將定時器集成到我的函數中。

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 

Sub Function1_Int_RandNumCounter() 

Dim Int_RandNum_X As Integer 
Dim Int_RandNum_Y As Integer 
Dim Count As Integer 

    For Count = 1 To Count = 1000000 
     Int_RandNum_X = Rnd(Now) ' Get rnd vals based on Now, built-in VBA property 
     Int_RandNum_Y = Rnd(Now) 
    Next Count 

' Call Function1_Dbl_RandNumCounter 

End Sub 

Sub Function1_Dbl_RandNumCounter() 

Dim Dbl_RandNum_X As Double, Dbl_RandNum_Y As Double, Count As Double 

    For Count = 1 To Count = 1000000 
     Dbl_RandNum_X = Rnd(Now) ' Get rnd vals based on Now, built-in VBA property 
     Dbl_RandNum_Y = Rnd(Now) 
    Next Count 

    Call Function1_Var_RandNumCounter 
End Sub 
Sub Function1_Var_RandNumCounter() 

Dim Var_RandNum_X, Var_RandNum_Y, Count As Variant 

    For Count = 1 To Count = 1000000 
     Var_RandNum_X = Rnd(Now) ' Get rnd vals based on Now, built-in VBA property 
     Var_RandNum_Y = Rnd(Now) 
    Next Count 

    Call Function1_Dec_RandNumCounter 

End Sub 
Sub Function1_Dec_RandNumCounter() 

Dim Count, Var_RandNum_X, dec_RandNum_X, Var_RandNum_Y, dec_RandNum_Y 

dec_RandNum_X = CDec(Var_RandNum_X) 
dec_RandNum_Y = CDec(Var_RandNum_Y) ' convert these vals to decimals 

    For Count = 1 To Count = 1000000 
     dec_RandNum_X = Rnd(Now) ' Get rnd vals based on Now, built-in VBA property 
     dec_RandNum_Y = Rnd(Now) 
    Next Count 

    Call Function2_BarGraph 

End Sub 
Sub Function2_BarGraph() 
' Put all of these vals in a 2D bar graph 
End Sub 

編輯:新VBA代碼(爲什麼我設置了該功能正常嗎?)

Sub Function1_Int_RandNumCounter() 
Dim Int_RandNum_X As Integer 
Dim Int_RandNum_Y As Integer 
Dim Count As Integer 
Dim oPM As PerformanceMonitor 
Dim Time_Int As Variant 

Time_Int = CDec(Time_Int) 

Set oPM = New PerformanceMonitor 
oPM.StartCounter 
For Count = 1 To Count = 1000000 
    Int_RandNum_X = Rnd(Now) ' Get rnd vals based on Now, built-in VBA property 
    Int_RandNum_Y = Rnd(Now) 
Next 

Time_Int = oPM.TimeElapsed 

' Call Function1_Dbl_RandNumCounter 

End Sub 
+0

這是VB.Net代碼,而不是VBA。 –

+1

僅供參考您的基準類型,但很少聲明它們。 dim a,b as T'只宣佈'b'爲'T'。 –

+2

我建議你閱讀:http://stackoverflow.com/questions/198409/how-do-you-test-running-time-of-vba-code – Rory

回答

2

添加一個新的類模塊到您的項目,把它PerformanceMonitor並粘貼從我掛線程的代碼在進級我的評論:

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 

現在作爲如何使用它,你需要申報和創建PerformanceMonitor類的實例的實例,然後調用其StartCounter方法在開始你想要的代碼,然後在最後調用它的TimeElapsed屬性來查看它花了多長時間(以毫秒爲單位)。例如:

Sub foo() 
    Dim n As Long 
    Dim oPM As PerformanceMonitor 

    Set oPM = New PerformanceMonitor 
    oPM.StartCounter 
    For n = 1 To 100000 
     Debug.Print n 
    Next 

    MsgBox oPM.TimeElapsed 
    Set oPM = Nothing 
End Sub 
+0

謝謝,我添加了該代碼,並調整了我的函數以包含此計時器中需要使用的部分。我如何聲明+創建一個PerformanceMonitor類,然後調用TimeElapsed?我想我理解其他部分。 –

+0

我添加了我的函數,它取代了你的第二個示例函數(參見上面的第三個代碼塊)。 –

+0

看起來很好 - 你有問題嗎? – Rory