秒表计时器开始计时代码
There is often more than one way to accomplish a particular coding task and one of the criteria that can be used to determine which method to use is to determine which one is the fastest. But how do you do that? You could try using displays of Visual Basic's Now() or Time() functions, and doing that will get you some results but they won't be very accurate since the accuracy of those functions is only about 1 second and that is huge compared to the time it takes to run a line, or even in most cases, thousands of lines of code. To improve on that you'll need to use an API. Some of the API possibilities are GetTickCount, TimeGetTime and QueryPerformanceCounter. Here's a chart of the commonly used methods and their accuracy.
通常,完成特定编码任务的方法不止一种,并且可以用来确定使用哪种方法的标准之一就是确定哪种方法最快。 但是,你是怎么做的? 您可以尝试使用Visual Basic的Now()或Time()函数的显示,这样做将获得一些结果,但是它们将不会非常准确,因为这些函数的准确性仅为1秒左右,与运行一行,甚至在大多数情况下,数千行代码所花费的时间。 要改善这一点,您需要使用API。 API的某些功能包括GetTickCount,TimeGetTime和QueryPerformanceCounter。 这是常用方法及其准确性的图表。
As you can see, GetTickCount and TimeGetTime are a hundred times more accurate than the VB functions and 10 ms is likely fine enough for any code that you want to time. QueryPerformanceCounter is much more accurate than that in that it can measure actual CPU cycles but most programmers will never need to do that.
如您所见,GetTickCount和TimeGetTime的精度比VB函数高100倍,对于任何您想计时的代码,10 ms可能就足够了。 QueryPerformanceCounter比它可以测量实际CPU周期的精度要高得多,但是大多数程序员都不需要这样做。
Here's a VB6 example that uses GetTickCount. In this case a comparison is done between 'Test1' where the Array function to fill an array, and 'Test2' where a more manual approach is used.
这是一个使用GetTickCount的VB6示例。 在这种情况下,将在“ Test1”(使用数组函数填充数组)和“ Test2”(使用更手动的方法)之间进行比较。
Each test uses a loop that repeats an action the same, large, number of times. The use of the large number of loops magnifies the results of the test and that is necessary because an individual line of code can be almost too fast to measure. It also helps smooth out small differences caused by random processes going on in the background.
每个测试都使用一个循环,该循环重复执行一次相同的,较大的次数。 大量循环的使用放大了测试的结果,这是必须的,因为单个代码行可能几乎太快而无法测量。 它还有助于消除由后台进行的随机过程引起的微小差异。
When you run this example you'll find the second method is faster than the first and that's because Test1's Array function requires that the target array be of type Variant, and Variants are slow (and large). Some people would still use the first because it requires less coding. In my opinion that's short-sighted because while you only write code once, the code may get executed thousands of times.
运行此示例时,您会发现第二种方法比第一种方法快,这是因为Test1的Array函数要求目标数组的类型为Variant,而Variants较慢(且较大)。 有些人仍然会使用第一个,因为它需要较少的编码。 我认为这是短视的,因为虽然您只编写一次代码,但是该代码可能被执行数千次。
Option Explicit
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Sub Command1_Click()
' Place this code in any Sub or Function
Dim lngStart As Long
Dim lngFinish As Long
Dim lngCounter As Long
Dim varArr As Variant
Dim strArr(2) As String
'TEST1
' Record the start "time"
lngStart = GetTickCount()
' Some process that you want to time
For lngCounter = 1 To 100000
varArr = Array("A", "B", "C")
Next
' Record the finish "time"
lngFinish = GetTickCount()
' Display the difference
Debug.Print "Test 1: " & CStr(lngFinish - lngStart)
'TEST2
' Record the start "time"
lngStart = GetTickCount()
' Some process that you want to time
For lngCounter = 1 To 100000
strArr(0) = "A"
strArr(1) = "B"
strArr(2) = "C"
Next
' Record the finish "time"
lngFinish = GetTickCount()
' Display the difference
Debug.Print "Test 2: " & CStr(lngFinish - lngStart)
End Sub
And here is an example using VBA in Excel where a comparison is made between two different ways to fill a range.
这是一个在Excel中使用VBA的示例,其中比较了两种不同的方式来填充范围。
Private Sub CommandButton1_Click()
' Place this code in any Sub or Function
Dim lngStart As Long
Dim lngFinish As Long
Dim lngCounter As Long
'TEST1
' Record the start "time"
lngStart = GetTickCount()
' Some process that you want to time
For lngCounter = 1 To 30000
Range("A" & lngCounter).Value = lngCounter
Next
' Record the finish "time"
lngFinish = GetTickCount()
' Display the difference
Debug.Print "Test1: " & CStr(lngFinish - lngStart)
'TEST2
' Record the start "time"
lngStart = GetTickCount()
' Some process that you want to time
For lngCounter = 1 To 30000
Cells(lngCounter, 1).Value = lngCounter
Next
' Record the finish "time"
lngFinish = GetTickCount()
' Display the difference
Debug.Print "Test2: " & CStr(lngFinish - lngStart)
End Sub
Finally, I never actually use it, but here's a QueryPerformanceCounter example.
最后,我从未真正使用过它,但是这里有一个QueryPerformanceCounter示例。
Option Explicit
Private Declare Function QueryPerformanceCounter Lib "Kernel32" (X As Currency) As Boolean
Private Declare Function QueryPerformanceFrequency Lib "Kernel32" (X As Currency) As Boolean
Private Sub CommandButton1_Click()
Dim frequency As Currency
Dim curStart As Currency
Dim curFinish As Currency
Dim lngCounter As Long
Dim varArr As Variant
' Get the frequency counter
' Return zero if hardware doesn't support high-res performance counters
If QueryPerformanceFrequency(frequency) = 0 Then
MsgBox "This computer doesn't support QueryPerformanceCounter"
Exit Sub
End If
' start timing
QueryPerformanceCounter curStart
' Code to be timed
For lngCounter = 1 To 100000
varArr = Array("A", "B", "C")
Next
' end timing
QueryPerformanceCounter curFinish
Debug.Print (curFinish - curStart) / frequency
End Sub
If you find that this article has been helpful, please click the “thumb’s up” button below. Doing so lets me know what is valuable for EE members and provides direction for future articles. It also provides me with positive feedback in the form of a few points. Thanks!
如果您发现本文对您有所帮助,请单击下面的“竖起大拇指”按钮。 这样做可以让我知道对EE成员有价值的内容,并为以后的文章提供指导。 它还以几点的形式为我提供了积极的反馈。 谢谢!
翻译自: https://www.experts-exchange.com/articles/10592/How-to-Time-Code.html
秒表计时器开始计时代码