这是我自己的速度测试结果(最后)。
在我的测试中,我使用了以下代码。我使用了 100 万次迭代来缩短等待时间。 -1 到 13 是给一些越界的工作。当需要阵列设置时,它包含在总时间中,但只完成一次。每个函数都有自己的调用过程,名称为 (X) 硬编码:
Dim str As String = ""
For i As Integer = 0 To 1000000
For j As Integer = -1 To 13
str = ComputeLabel_X(j, False, False)
str = ComputeLabel_X(j, True, False)
str = ComputeLabel_X(j, False, True)
Next
Next
在使用 F5(出错时中断代码)和 Ctrl-F5(在调试器之外运行)运行代码时,我也得到了不同的结果。我猜第二个对 SSRS 代码环境更有效,因为没有任何东西会附加到进程来调试它。
所有结果都无需调试 (Ctrl-F5) 即可编译。
- Russ:613 毫秒(添加了边界检查)
- Erik:614 毫秒(与 Russ 相同,但数组填充为数组文字 {} 而不是单个语句)
- Erik2:526 毫秒(0 到 12,额外的 0 到 2,无边界检查)
- 史蒂夫:660 毫秒
- Steve2:873 毫秒(删除个别 If 语句的 ElseIf)
- 新:2977 毫秒(我之前回答的第一个想法)
- 初始发布:3915 毫秒 * - 修改为正确(小了 10 倍)
- 原文:3947 ms(你从未见过的版本,我优化后在这里发布的版本)
- 选择:11068 毫秒
- BigArray:12565 毫秒(用数学计算大数组的索引)
尽管较高值的执行时间可能会波动多达 100 毫秒,但排名往往保持一致,除了不断交换的 Russ 和 Erik 版本。
要点:
构建一次数组是无关紧要的。将其作为单独的语句或作为数组文字 {} 是相同的。
对数组方法进行边界检查的成本增加了 20%。
直观地扩展整个事物似乎应该是最快的,但事实并非如此。我不知道为什么。也许它与处理器缓存行大小和预加载权衡有关,或者类似的东西。
我从原始函数对我在问题中发布的函数所做的唯一真正更改是:1) 从每个 case 语句返回,而不是将字符串分配给变量并在最后返回(加上删除变量),2)交换独立的 If Flag 语句顺序并将第二个 If 更改为 ElseIf。 1% 的提升是微不足道的
似乎我应该能够从我列为“新”的版本(我发布的另一个答案中的第一个查询)表现如此糟糕这一事实中概括出一些东西。它是更长的字符串吗?是不是无论在程序的哪个位置返回都一样快,但是退出Case语句执行更多指令却很慢?
Russ 的数组版本最快。数组查找比使用字符串连接的 case 语句更快。
此时我不知道如何解释为什么新版本更快。
Choose 功能超级超级慢。
由于这些测试,我必须将这个问题的答案授予声称我无法优化给定代码的 nobugz。到目前为止,他是对的!
更新:对于我在测试初始发布版本的迭代次数上留下零的错误,我感到非常抱歉。事情已经得到纠正。
附录:(更正的)测试代码:
Module Module1
Dim _Labels(12) As String
Dim _ConditionalLabels(12) As String
Dim _HeldLabels(12) As String
Dim Labels() As String
Dim ConditionalLabels() As String
Dim HeldLabels() As String
Dim OrderLabelsBigArray(38) As String
Sub Main()
Dim sw As New Stopwatch()
sw.Start()
ComputeLabelsFirstPosted()
sw.Stop()
Console.WriteLine("FirstPosted " & sw.ElapsedMilliseconds & " ms")
sw.Reset()
sw.Start()
ComputeLabelsRuss()
sw.Stop()
Console.WriteLine("Russ " & sw.ElapsedMilliseconds & " ms")
sw.Reset()
sw.Start()
ComputeLabelsErik()
sw.Stop()
Console.WriteLine("Erik " & sw.ElapsedMilliseconds & " ms")
sw.Reset()
sw.Start()
ComputeLabelsErik2()
sw.Stop()
Console.WriteLine("Erik2 " & sw.ElapsedMilliseconds & " ms")
sw.Reset()
sw.Start()
ComputeLabelsBigArray()
sw.Stop()
Console.WriteLine("BigArray " & sw.ElapsedMilliseconds & " ms")
sw.Reset()
sw.Start()
ComputeLabelsSteve()
sw.Stop()
Console.WriteLine("Steve " & sw.ElapsedMilliseconds & " ms")
sw.Reset()
sw.Start()
ComputeLabelsSteve2()
sw.Stop()
Console.WriteLine("Steve2 " & sw.ElapsedMilliseconds & " ms")
sw.Reset()
sw.Start()
ComputeLabelsNew()
sw.Stop()
Console.WriteLine("New " & sw.ElapsedMilliseconds & " ms")
sw.Reset()
sw.Start()
ComputeLabelsChoose()
sw.Stop()
Console.WriteLine("Choose " & sw.ElapsedMilliseconds & " ms")
sw.Reset()
sw.Start()
ComputeLabelsOriginal()
sw.Stop()
Console.WriteLine("Original " & sw.ElapsedMilliseconds & " ms")
Console.Read()
End Sub
Public Sub ComputeLabelsFirstPosted()
Dim str As String = ""
For i As Integer = 0 To 1000000
For j As Integer = -1 To 13
str = ComputeLabelFirstPosted(j, False, False)
str = ComputeLabelFirstPosted(j, True, False)
str = ComputeLabelFirstPosted(j, False, True)
Next
Next
End Sub
Public Function ComputeLabelFirstPosted(ByVal Action As Integer, ByVal IsHeld As Boolean, ByVal IsConditional As Boolean) As String
Dim Prefix As String = ""
If IsConditional Then
Prefix = "Conditional "
ElseIf IsHeld Then
Prefix = "Held "
End If
Select Case Action
Case 0
Return ""
Case 1
Return Prefix & "Cancelled"
Case 2
Return Prefix & "Discontinued"
Case 3
Return Prefix & "Suspended"
Case 4
Return Prefix & "Unsuspended"
Case 6
Return Prefix & "Collected"
Case 7
Return Prefix & "Released from Hold"
Case 8
Return Prefix & "Modified"
Case 9
Return Prefix & "Discontinued for the Future"
Case 10
Return Prefix & "Verified"
Case 11
Return Prefix & "Modified And Verified"
Case 12
Return "Hold " & Prefix & "Cancelled"
Case Else
Return ""
End Select
End Function
Sub ComputeLabelsRuss()
_Labels(0) = ""
_Labels(1) = "Cancelled"
_Labels(2) = "Discontinued"
_Labels(3) = "Suspended"
_Labels(4) = "Unsuspended"
_Labels(6) = "Collected"
_Labels(7) = "Released from Hold"
_Labels(8) = "Modified"
_Labels(9) = "Discontinued for the Future"
_Labels(10) = "Verified"
_Labels(11) = "Modified And Verified"
_Labels(12) = "Hold Cancelled"
_ConditionalLabels(0) = ""
_ConditionalLabels(1) = "Conditional Cancelled"
_ConditionalLabels(2) = "Conditional Discontinued"
_ConditionalLabels(3) = "Conditional Suspended"
_ConditionalLabels(4) = "Conditional Unsuspended"
_ConditionalLabels(6) = "Conditional Collected"
_ConditionalLabels(7) = "Conditional Released from Hold"
_ConditionalLabels(8) = "Conditional Modified"
_ConditionalLabels(9) = "Conditional Discontinued for the Future"
_ConditionalLabels(10) = "Conditional Verified"
_ConditionalLabels(11) = "Conditional Modified And Verified"
_ConditionalLabels(12) = "Hold Conditional Cancelled"
_HeldLabels(0) = ""
_HeldLabels(1) = "Held Cancelled"
_HeldLabels(2) = "Held Discontinued"
_HeldLabels(3) = "Held Suspended"
_HeldLabels(4) = "Held Unsuspended"
_HeldLabels(6) = "Held Collected"
_HeldLabels(7) = "Held Released from Hold"
_HeldLabels(8) = "Held Modified"
_HeldLabels(9) = "Held Discontinued for the Future"
_HeldLabels(10) = "Held Verified"
_HeldLabels(11) = "Held Modified And Verified"
_HeldLabels(12) = "Hold Held Cancelled"
Dim str As String = ""
For i As Integer = 0 To 1000000
For j As Integer = -1 To 13
str = ComputeLabelRuss(j, False, False)
str = ComputeLabelRuss(j, True, False)
str = ComputeLabelRuss(j, False, True)
Next
Next
End Sub
Public Function ComputeLabelRuss(ByVal Action As Integer, ByVal Held As Boolean, ByVal Conditional As Boolean) As String
If Action < 0 OrElse Action > 12 Then Return ""
If Conditional Then Return _ConditionalLabels(Action)
If Held Then Return _HeldLabels(Action)
Return _Labels(Action)
End Function
Public Sub ComputeLabelsNew()
Dim str As String = ""
For i As Integer = 0 To 1000000
For j As Integer = -1 To 13
str = ComputeLabelNew(j, False, False)
str = ComputeLabelNew(j, True, False)
str = ComputeLabelNew(j, False, True)
Next
Next
End Sub
Public Function ComputeLabelNew(ByVal Action As Integer, ByVal IsHeld As Boolean, ByVal IsConditional As Boolean) As String
Dim Status As String = ""
Select Case Action
Case 0
Return ""
Case 1
Status = "Cancelled"
Case 2
Status = "Discontinued"
Case 3
Status = "Suspended"
Case 4
Status = "Unsuspended"
Case 6
Status = "Collected"
Case 7
Status = "Released from Hold"
Case 8
Status = "Modified"
Case 9
Status = "Discontinued for the Future"
Case 10
Status = "Verified"
Case 11
Status = "Modified And Verified"
Case 12
If IsConditional Then Return "Hold Conditional Cancelled"
If IsHeld Then Return "Hold Held Cancelled"
Return "Hold Cancelled"
Case Else
Return ""
End Select
If IsConditional Then Return "Conditional " & Status
If IsHeld Then Return "Held " & Status
Return Status
End Function
Sub ComputeLabelsErik()
Labels = New String() {"", "Cancelled", "Discontinued", "Suspended", "Unsuspended", "", "Collected", "Released from Hold", "Modified", "Discontinued for the Future", "Verified", "Modified And Verified", "Hold Cancelled"}
ConditionalLabels = New String() {"", "Conditional Cancelled", "Conditional Discontinued", "Conditional Suspended", "Conditional Unsuspended", "Conditional ", "Conditional Collected", "Conditional Released from Hold", "Conditional Modified", "Conditional Discontinued for the Future", "Conditional Verified", "Conditional Modified And Verified", "Hold Cancelled"}
HeldLabels = New String() {"", "Held Cancelled", "Held Discontinued", "Held Suspended", "Held Unsuspended", "Held ", "Held Collected", "Held Released from Hold", "Held Modified", "Held Discontinued for the Future", "Held Verified", "Held Modified And Verified", "Hold Cancelled"}
Dim str As String = ""
For i As Integer = 0 To 1000000
For j As Integer = -1 To 13
str = ComputeLabelErik(j, False, False)
str = ComputeLabelErik(j, True, False)
str = ComputeLabelErik(j, False, True)
Next
Next
End Sub
Public Function ComputeLabelErik(ByVal Action As Integer, ByVal Held As Boolean, ByVal Conditional As Boolean) As String
If Action < 0 OrElse Action > 12 Then Return ""
If Conditional Then Return ConditionalLabels(Action)
If Held Then Return HeldLabels(Action)
Return Labels(Action)
End Function
Sub ComputeLabelsErik2()
Dim str As String = ""
For i As Integer = 0 To 1000000
For j As Integer = 0 To 12
str = ComputeLabelErik2(j, False, False)
str = ComputeLabelErik2(j, True, False)
str = ComputeLabelErik2(j, False, True)
Next
For j As Integer = 1 To 2
str = ComputeLabelErik2(j, False, False)
str = ComputeLabelErik2(j, True, False)
str = ComputeLabelErik2(j, False, True)
Next
Next
End Sub
Public Function ComputeLabelErik2(ByVal Action As Integer, ByVal Held As Boolean, ByVal Conditional As Boolean) As String
If Conditional Then Return ConditionalLabels(Action)
If Held Then Return HeldLabels(Action)
Return Labels(Action)
End Function
Public Sub ComputeLabelsOriginal()
Dim str As String = ""
For i As Integer = 0 To 1000000
For j As Integer = -1 To 13
str = ComputeLabelOriginal(j, False, False)
str = ComputeLabelOriginal(j, True, False)
str = ComputeLabelOriginal(j, False, True)
Next
Next
End Sub
Public Function ComputeLabelOriginal(ByVal Action As Integer, ByVal bIsHeld As Boolean, _
ByVal bIsConditional As Boolean) As String
Dim strReprintLabel As String = ""
Dim strOrderActionPrefix As String = ""
If (bIsHeld) Then
strOrderActionPrefix = "Held "
End If
If (bIsConditional) Then
strOrderActionPrefix = "Conditional "
End If
Select Case Action
Case 0 ' Normal Order
strReprintLabel = ""
Case 1
strReprintLabel = strOrderActionPrefix & "Order Cancelled"
Case 2
strReprintLabel = strOrderActionPrefix & "Order Discontinued"
Case 3
strReprintLabel = strOrderActionPrefix & "Order Suspended"
Case 4
strReprintLabel = strOrderActionPrefix & "Order Unsuspended"
Case 6
strReprintLabel = strOrderActionPrefix & "Order Collected"
Case 7
strReprintLabel = strOrderActionPrefix & "Order Released from Hold"
Case 8
strReprintLabel = strOrderActionPrefix & "Order Modified"
Case 9
strReprintLabel = strOrderActionPrefix & "Order Discontinued for the Future"
Case 10
strReprintLabel = strOrderActionPrefix & "Order Verified"
Case 11
strReprintLabel = strOrderActionPrefix & "Order Modified And Verified"
Case 12
strReprintLabel = "Hold " & strOrderActionPrefix & "Order Cancelled"
Case Else
strReprintLabel = ""
End Select
Return strReprintLabel
End Function
Sub ComputeLabelsSteve2()
Dim str As String = ""
For i As Integer = 0 To 1000000
For j As Integer = -1 To 13
str = ComputeLabelSteve2(j, False, False)
str = ComputeLabelSteve2(j, True, False)
str = ComputeLabelSteve2(j, False, True)
Next
Next
End Sub
Public Function ComputeLabelSteve2(ByVal Action As Integer, ByVal IsHeld As Boolean, ByVal IsConditional As Boolean) As String
Select Case Action
Case 0
Return ""
Case 1
If IsConditional Then Return "Conditional Cancelled"
If IsHeld Then Return "Held Cancelled"
Return "Cancelled"
Case 2
If IsConditional Then Return "Conditional Discontinued"
If IsHeld Then Return "Held Discontinued"
Return "Discontinued"
Case 3
If IsConditional Then Return "Conditional Suspended"
If IsHeld Then Return "Held Suspended"
Return "Suspended"
Case 4
If IsConditional Then Return "Conditional Unsuspended"
If IsHeld Then Return "Held Unsuspended"
Return "Unsuspended"
Case 6
If IsConditional Then Return "Conditional Collected"
If IsHeld Then Return "Held Collected"
Return "Collected"
Case 7
If IsConditional Then Return "Conditional Released from Hold"
If IsHeld Then Return "Held Released from Hold"
Return "Released from Hold"
Case 8
If IsConditional Then Return "Conditional Modified"
If IsHeld Then Return "Held Modified"
Return "Modified"
Case 9
If IsConditional Then Return "Conditional Discontinued for the Future"
If IsHeld Then Return "Held Discontinued for the Future"
Return "Discontinued for the Future"
Case 10
If IsConditional Then Return "Conditional Verified"
If IsHeld Then Return "Held Verified"
Return "Verified"
Case 11
If IsConditional Then Return "Conditional Modified And Verified"
If IsHeld Then Return "Held Modified And Verified"
Return "Modified And Verified"
Case 12
If IsConditional Then Return "Hold Conditional Cancelled"
If IsHeld Then Return "Hold Held Cancelled"
Return "Hold Cancelled"
Case Else
Return ""
End Select
End Function
Sub ComputeLabelsSteve()
Dim str As String = ""
For i As Integer = 0 To 1000000
For j As Integer = -1 To 13
str = ComputeLabelSteve(j, False, False)
str = ComputeLabelSteve(j, True, False)
str = ComputeLabelSteve(j, False, True)
Next
Next
End Sub
Public Function ComputeLabelSteve(ByVal Action As Integer, ByVal IsHeld As Boolean, ByVal IsConditional As Boolean) As String
Select Case Action
Case 0
Return ""
Case 1
If IsConditional Then
Return "Conditional Cancelled"
ElseIf IsHeld Then
Return "Held Cancelled"
Else
Return "Cancelled"
End If
Case 2
If IsConditional Then
Return "Conditional Discontinued"
ElseIf IsHeld Then
Return "Held Discontinued"
Else
Return "Discontinued"
End If
Case 3
If IsConditional Then
Return "Conditional Suspended"
ElseIf IsHeld Then
Return "Held Suspended"
Else
Return "Suspended"
End If
Case 4
If IsConditional Then
Return "Conditional Unsuspended"
ElseIf IsHeld Then
Return "Held Unsuspended"
Else
Return "Unsuspended"
End If
Case 6
If IsConditional Then
Return "Conditional Collected"
ElseIf IsHeld Then
Return "Held Collected"
Else
Return "Collected"
End If
Case 7
If IsConditional Then
Return "Conditional Released from Hold"
ElseIf IsHeld Then
Return "Held Released from Hold"
Else
Return "Released from Hold"
End If
Case 8
If IsConditional Then
Return "Conditional Modified"
ElseIf IsHeld Then
Return "Held Modified"
Else
Return "Modified"
End If
Case 9
If IsConditional Then
Return "Conditional Discontinued for the Future"
ElseIf IsHeld Then
Return "Held Discontinued for the Future"
Else
Return "Discontinued for the Future"
End If
Case 10
If IsConditional Then
Return "Conditional Verified"
ElseIf IsHeld Then
Return "Held Verified"
Else
Return "Verified"
End If
Case 11
If IsConditional Then
Return "Conditional Modified And Verified"
ElseIf IsHeld Then
Return "Held Modified And Verified"
Else
Return "Modified And Verified"
End If
Case 12
If IsConditional Then
Return "Hold Conditional Cancelled"
ElseIf IsHeld Then
Return "Hold Held Cancelled"
Else
Return "Hold Cancelled"
End If
Case Else
Return ""
End Select
End Function
Sub ComputeLabelsChoose()
Dim str As String = ""
For i As Integer = 0 To 1000000
For j As Integer = -1 To 13
str = ComputeLabelChoose(j, False, False)
str = ComputeLabelChoose(j, True, False)
str = ComputeLabelChoose(j, False, True)
Next
Next
End Sub
Public Function ComputeLabelChoose(ByVal Action As Integer, ByVal IsHeld As Boolean, ByVal IsConditional As Boolean) As String
Dim Status As String = ""
Select Case Action
Case 0, 5
Return ""
Case 1 To 11
Status = Choose(Action, "Cancelled", "Discontinued", "Suspended", _
"Unsuspended", "Collected", "Released from Hold", "Modified", _
"Discontinued for the Future", "Verified", "Modified And Verified")
Case 12
If IsConditional Then
Return "Hold Conditional Cancelled"
ElseIf IsHeld Then
Return "Hold Held Cancelled"
Else
Return "Hold Cancelled"
End If
Case Else
Return ""
End Select
If IsConditional Then Return "Conditional " & Status
If IsHeld Then Return "Held " & Status
Return Status
End Function
Sub ComputeLabelsBigArray()
OrderLabelsBigArray = New String() {"", "Cancelled", "Discontinued", "Suspended", "Unsuspended", "", "Collected", "Released from Hold", "Modified", "Discontinued for the Future", "Verified", "Modified And Verified", "Hold Cancelled", _
"", "Conditional Cancelled", "Conditional Discontinued", "Conditional Suspended", "Conditional Unsuspended", "Conditional ", "Conditional Collected", "Conditional Released from Hold", "Conditional Modified", "Conditional Discontinued for the Future", "Conditional Verified", "Conditional Modified And Verified", "Hold Cancelled", _
"", "Held Cancelled", "Held Discontinued", "Held Suspended", "Held Unsuspended", "Held ", "Held Collected", "Held Released from Hold", "Held Modified", "Held Discontinued for the Future", "Held Verified", "Held Modified And Verified", "Hold Cancelled"}
Dim str As String = ""
For i As Integer = 0 To 1000000
For j As Integer = -1 To 13
str = ComputeLabelChoose(j, False, False)
str = ComputeLabelChoose(j, True, False)
str = ComputeLabelChoose(j, False, True)
Next
Next
End Sub
Public Function ComputeLabelBigArray(ByVal Action As Integer, ByVal IsHeld As Boolean, ByVal IsConditional As Boolean) As String
If Action < 0 OrElse Action >= 13 Then Return ""
Return OrderLabelsBigArray(Action - IsConditional * 13 - (IsHeld AndAlso Not IsConditional) * 26)
End Function
End Module
现在如果我犯了另一个错误,有人可以帮助找到它。