आप VBA कोड के रनिंग समय का परीक्षण कैसे करते हैं?


95

क्या VBA में कोई कोड है, मैं इसके साथ एक फंक्शन को लपेट सकता हूं, जिससे मुझे यह पता चल जाएगा कि इसे चलाने में कितना समय लगा है, ताकि मैं अलग-अलग कार्यों के समय की तुलना कर सकूं?

जवाबों:


81

जब तक आपके कार्य बहुत धीमे नहीं होते, तब तक आपको एक उच्च-रिज़ॉल्यूशन टाइमर की आवश्यकता होती है। सबसे सटीक मैं जानता हूं QueryPerformanceCounter। अधिक जानकारी के लिए इसे Google निम्नलिखित को एक कक्षा में धकेलने का प्रयास करें, इसे 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
मैंने इसे एक्सेल VBA (इस KB लेख में उल्लिखित ओवरहेड में जोड़कर) को लागू किया: support.microsoft.com/kb/172338 । इसने बहुत अच्छा काम किया। धन्यवाद।
लांस रॉबर्ट्स

2
धन्यवाद, यह मेरे लिए भी अच्छा काम करता है। TimeElapsed()मिलीसेकंड में परिणाम देता है। मैंने किसी भी ओवरहेड मुआवजे को लागू नहीं किया क्योंकि मैं सही सटीकता की तुलना में ओवरहेड गणना में हकलाने के प्रभाव के बारे में अधिक चिंतित था।
जस्टिन

2
यह बहुत अधिक सुना है (कोड की पंक्तियों में प्रबंधन करने के लिए) - यदि आप ~ 10ms सटीकता के साथ रह सकते हैं, तो नीचे दिए गए कोडक का जवाब कोड की एक पंक्ति में एक ही चीज़ देता है ( GetTickCountकर्नेल से आयात करना )।
BrainSlugs83

आप कैसे उपयोग करते हैं StartCounterऔर TimeElapsed? मैंने CTimerशुरुआत में एक उदाहरण टाइमर किया था और With StartCounterमैंने .StartCounterअपने उप के शुरू होने के बाद लिखा था .TimeElapsedऔर इसने मुझे जवाब दिया Invalid use of property। जब मैं .StartCounterअकेला होता हूं तो यह बताता है कि कोई वस्तु सेट नहीं है।
मोनिका

एक्सेल 2010 के लिए: Declare PtrSafe Function stackoverflow.com/questions/21611744/…
user3226167

48

वीबीए में टाइमर फ़ंक्शन आपको आधी रात के बाद से लेकर सेकंड के 1/100 तक की संख्या देता है।

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

18
यह काम नहीं करेगा - आप उस तरह औसत लेने से अधिक संकल्प नहीं प्राप्त कर सकते हैं।
एंड्रयू स्कैग्नेली

3
फिर भी, यदि आप VBA में प्रदर्शन माप रहे हैं, तो दूसरे रिज़ॉल्यूशन का 1/100 वाँ भाग प्राप्त करना बुरा नहीं है। - अकेले टाइमिंग कॉल को आमंत्रित करने से एमएस की एक जोड़ी ले सकता है। यदि कॉल इतनी तेज़ है कि आपको उस समय के लिए अधिक रिज़ॉल्यूशन की आवश्यकता है, तो आपको संभवतः उस कॉल के बारे में प्रदर्शन डेटा की आवश्यकता नहीं है।
BrainSlugs83

नोट: मैक पर टाइमर केवल एक सेकंड के लिए सटीक है - और यह नकारात्मक संख्या प्राप्त कर सकता है यदि यह आधी रात से पहले शुरू होता है और आधी रात के बाद समाप्त होता है
TmTron

32

यदि आप स्टॉपवॉच की तरह समय को वापस करने की कोशिश कर रहे हैं तो आप निम्न एपीआई का उपयोग कर सकते हैं जो सिस्टम स्टार्टअप के बाद से मिलीसेकंड में समय लौटाता है:

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 के लिए काम नहीं कर रहा था बहुत जरूरत कार्य के लिए जटिल थी)


यह एक बेहतरीन जवाब है। ध्यान दें: परिशुद्धता दिए गए डेटा की मिलीसेकेंड में है, तथापि, काउंटर केवल है सही 1 के बारे में करने के लिए / एक दूसरे की 100 वीं (यह है कि, यह बंद 10 से 16 एमएस द्वारा हो सकता है) MSDN के माध्यम से: msdn.microsoft.com / en-us / पुस्तकालय / खिड़कियां / डेस्कटॉप / ...
BrainSlugs83

हम्म, अगर संकल्प यहाँ टाइमर के साथ के रूप में एक ही है, तो मैं टाइमर के साथ जाना होगा
कोडक

क्या Public Declare Function ...हिस्सा है? यह मेरा खदान के तल पर अपना कोड जोड़ते समय एक त्रुटि पैदा करता है
मोनिका

आपको सार्वजनिक घोषणा को अपने मॉड्यूल के शीर्ष पर ले जाने की आवश्यकता है
कोडक

4

Newbees के लिए, ये लिंक बताते हैं कि आप उस समय के सभी सबस्क्रिप्शन की ऑटोमैटिक प्रोफाइलिंग कैसे कर सकते हैं, जिसे आप मॉनिटर करना चाहते हैं:

http://www.nullskull.com/a/1602/profiling-and-optimizing-vba.aspx

http://sites.mcpher.com/share/Home/excelquirks/optimizationlink http://sites.mcpher.com/share/Home/excelquirks/downlable-items में procProfiler.zip देखें


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


2

हमने कई वर्षों से मिलीसेकंड सटीकता के लिए winmm.dll में टाइमगेट टाइम पर आधारित एक समाधान का उपयोग किया है। देखHttp://www.aboutvb.de/kom/artikel/komstopwatch.htm

लेख जर्मन में है, लेकिन डाउनलोड में कोड (एक VBA वर्ग जो dll फ़ंक्शन कॉल को लपेटता है) लेख को पढ़ने में सक्षम होने के बिना उपयोग करने और समझने के लिए सरल है।


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/100 सेकंड का एक व्यक्तिगत रूप से, लेकिन मिलीसेकंड टाइमर आपको इनमें से सबसे सटीक रन समय देगा 3. मैंने भी आपको पढ़ा है आधी रात को पार करते समय अगर ऐसा होता है तो गलत तरीके से पढ़ा जा सकता है, एक दुर्लभ उदाहरण लेकिन सिर्फ FYI करें।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.