Làm thế nào để bạn kiểm tra thời gian chạy của mã VBA?


Câu trả lời:


81

Trừ khi các chức năng của bạn rất chậm, bạn sẽ cần một bộ đếm thời gian có độ phân giải rất cao. Cái chính xác nhất mà tôi biết là QueryPerformanceCounter. Google nó để biết thêm thông tin. Hãy thử đẩy phần sau vào một lớp, gọi nó là CTimersay, sau đó bạn có thể tạo một phiên bản ở đâu đó trên toàn cầu và chỉ cần gọi .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
Tôi đã triển khai điều này trong Excel VBA (thêm vào Overhead như được đề cập trong bài viết KB này: support.microsoft.com/kb/172338 . Nó hoạt động tốt. Cảm ơn.
Lance Roberts

2
Cảm ơn, điều này cũng hoạt động tốt cho tôi. TimeElapsed()cho kết quả tính bằng mili giây. Tôi không thực hiện bất kỳ khoản bồi thường chi phí nào vì tôi lo lắng về ảnh hưởng của hiện tượng nói lắp trong tính toán chi phí hơn là độ chính xác hoàn hảo.
Justin

2
Đó là rất nhiều điều nghe được (trong các dòng mã cần quản lý) - nếu bạn có thể sống với độ chính xác ~ 10ms, câu trả lời của @ Kodak dưới đây cho điều tương tự trong một dòng mã (nhập GetTickCounttừ kernel32).
BrainSlugs83

Làm thế nào để bạn sử dụng StartCounterTimeElapsed? Tôi đã làm một ví dụ Timer CTimerở đầu và With StartCountertôi chỉ viết .StartCountersau khi phụ của tôi bắt đầu .TimeElapsedvà nó đã trả lời tôi Invalid use of property. Khi tôi mặc .StartCounterkệ nó cho tôi biết một đối tượng chưa được thiết lập.
Khởi nghĩa cho Monica

Đối với excel 2010: Declare PtrSafe Function stackoverflow.com/questions/21611744/…
user3226167

48

Chức năng Hẹn giờ trong VBA cung cấp cho bạn số giây đã trôi qua kể từ nửa đêm, đến 1/100 giây.

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

18
Điều đó sẽ không hiệu quả - bạn không thể có thêm độ phân giải khi lấy mức trung bình như vậy.
Andrew Scagnelli

3
Tuy nhiên, nếu bạn đang đo hiệu suất trong VBA, nhận được độ phân giải 1/100 giây không phải là tồi. - Việc gọi các cuộc gọi thời gian một mình có thể mất vài mili giây. Nếu cuộc gọi quá nhanh đến mức bạn cần nhiều độ phân giải như vậy để xử lý thời gian, có thể bạn không cần dữ liệu hiệu suất về cuộc gọi đó.
BrainSlugs83 Ngày

lưu ý: trên Mac, Bộ hẹn giờ chỉ chính xác đến một giây - và điều này có thể nhận được số âm nếu nó bắt đầu trước nửa đêm và kết thúc sau nửa đêm
TmTron

32

Nếu bạn đang cố gắng trả lại thời gian giống như một chiếc đồng hồ bấm giờ, bạn có thể sử dụng API sau để trả về thời gian tính bằng mili giây kể từ khi khởi động hệ thống:

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

sau http://www.pcreview.co.uk/forums/grab-time-milliseconds-included-vba-t994765.html (vì timeGetTime trong winmm.dll không hoạt động đối với tôi và QueryPerformanceCounter quá phức tạp đối với tác vụ cần thiết)


Đây là một câu trả lời tuyệt vời. Lưu ý: độ chính xác của dữ liệu trả về tính bằng mili giây, tuy nhiên, bộ đếm chỉ chính xác đến khoảng 1/100 giây (nghĩa là, nó có thể bị lệch từ 10 đến 16 mili giây) qua MSDN: msdn.microsoft.com / en-us / library / windows / desktop /…
BrainSlugs83 Ngày

hmm, nếu độ phân giải ở đây giống như với Bộ hẹn giờ thì tôi sẽ sử dụng Bộ hẹn giờ
Kodak

Phần là Public Declare Function ...gì? Nó tạo ra một lỗi khi thêm mã của bạn ở dưới cùng của tôi
Revolucion cho Monica

Bạn cần chuyển tuyên bố công khai này lên đầu mô-đun của mình
Kodak


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

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

Đầu ra:

RunTime: 00:00:02


2

Chúng tôi đã sử dụng một giải pháp dựa trên timeGetTime trong winmm.dll cho độ chính xác mili giây trong nhiều năm. Xem http://www.aboutvb.de/kom/artikel/komstopwatch.htm

Bài viết bằng tiếng Đức, nhưng mã trong bản tải xuống (một lớp VBA gói lệnh gọi hàm dll) đủ đơn giản để sử dụng và hiểu mà không cần đọc bài viết.


1

Giây có 2 dấu cách thập phân:

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

định dạng giây

Mili giây:

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

định dạng mili giây

Mili giây với dấu phân cách dấu phẩy:

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

Mili giây với dấu phân cách dấu phẩy

Chỉ để lại điều này ở đây cho bất kỳ ai đang tìm kiếm một bộ đếm thời gian đơn giản được định dạng từ giây đến 2 dấu cách thập phân như tôi. Đây là những bộ hẹn giờ ngắn và ngọt ngào mà tôi thích sử dụng. Chúng chỉ chiếm một dòng mã ở đầu sub hoặc chức năng và một dòng mã lại ở cuối. Những điều này không có nghĩa là chính xác đến điên rồ, tôi thường không quan tâm đến bất cứ điều gì ít hơn 1/100 giây cá nhân, nhưng bộ đếm thời gian mili giây sẽ cung cấp cho bạn thời gian chạy chính xác nhất trong số 3. Tôi cũng đã đọc bạn có thể đọc sai nếu nó xảy ra chạy khi vượt quá nửa đêm, một trường hợp hiếm gặp nhưng chỉ là FYI.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.