VB.Net功能优化(SSRS报告代码)

时间:2010-01-14 19:38:43

标签: vb.net optimization reporting-services

我最近遇到了以下代码,并希望对其进行优化:

Public Shared Function ComputeLabel(ByVal Action As Integer, ByVal Flag1 As Boolean, ByVal Flag2 As Boolean) As String
   Dim Prefix As String = ""

   If Flag2 Then
      Prefix = "Conditional "
   ElseIf Flag1 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

请注意,操作0是最常见的情况。

好的,我已经清理过这个函数了 - 它使用了一个变量并在最后返回它,并且使用Return似乎更好。但另外,我认为在报告执行开始时构建数组会更好,然后每次调用此函数时只访问数组元素,而不是使用Select语句。但是案例12使事情变得更加复杂(正如你所看到的,它在中间而不是在开头添加了前缀。)

您认为最好的方式是什么:

  • 一次为这三种情况构建一个39个元素的阵列:

    Private Shared OrderActions() As String = {"", "Cancelled", ...}
    

    然后在访问它的函数中如下:

    If Action < 0 OrElse Action >= 13 Then Return ""
    Return OrderActions(Action - Flag2 * 13 - (Flag1 AndAlso Not Flag2) * 26)
    
  • 使用带有替换的13元素数组(类似于Return Replace(LabelList(Action), "{Prefix}", Prefix)?)

  • 使用带有Action 12特殊情况的12元素数组。

  • 我还没有想到的其他东西。

更新1:我的格式已关闭,因此选项可能不清楚。它现在应该更具可读性。

更新2:我从性能角度看你的意思,完全扩展所有案例并使用简单的变量赋值可能是最快的。所以...让我们说最高速度不是首要任务,但整体优雅(干净的代码和速度的组合)。人们也有机会对此采取行动吗?我会投票给所有在这个问题的所有方面提供合理帮助的人。

更新3:我忽略了一个额外的考虑因素是一些没有经验的程序员将会长期维护,所以它确实需要易于理解。我想从这个角度来看,我试图缩短代码的例子并不好。

更新4:测试是王者!一旦我受到启发进行一些速度测试,我得到了一些有趣的结果。请参阅下面的答案。

6 个答案:

答案 0 :(得分:2)

如果这是一个瓶颈并且速度是优先考虑的话,那么我的第一个建议就是通过复制你的大部分逻辑来消除字符串连接。这将使功能更大,更不易读,但也许这对速度来说是值得的......

Public Shared Function ComputeLabel(ByVal Action As Integer, ByVal Flag1 As Boolean, ByVal Flag2 As Boolean) As String
   Select Case nHVCOrderAction
        Case 0
            Return ""
        Case 1
            If Flag2 Then
                Return "Conditional Cancelled"
            ElseIf Flag1 Then
                Return "Held Cancelled"
            Else
                Return "Cancelled"
            End If
        Case 2
            If Flag2 Then
                Return "Conditional Discontinued"
            ElseIf Flag1 Then
                Return "Held Discontinued"
            Else
                Return "Discontinued"
            End If
        ' And so on...
   End Select
End Function

相对而言,代码中的字符串连接可能比这里的整数和布尔比较操作要慢。因此,通过足够的重复,你会发现这种方法的速度有明显的提高。

更新:

我写了一个快速&amp;脏的VB.NET控制台应用程序来测试你的原始代码与我的。这是我为每个循环运行的循环(我没有写出所有可能的组合,但你明白了):

    Dim sw As New Stopwatch()
    sw.Start()

    For i As Integer = 0 To 10000000
        str = ComputeLabel(0, True, False)
        str = ComputeLabel(1, False, False)
        str = ComputeLabel(0, False, False)
        str = ComputeLabel(2, False, False)
        str = ComputeLabel(1, False, True)
        str = ComputeLabel(2, True, True)
        str = ComputeLabel(4, False, True)
        str = ComputeLabel(7, True, True)
        str = ComputeLabel(12, False, True)
    Next

    sw.Stop()
    Console.WriteLine(sw.ElapsedMilliseconds & " ms")

以下是时间:

旧方法:6189 ms

新方法:1374毫秒

因此,通过删除字符串连接并扩展每种情况的条件,可以提高5倍的速度。当然,你可能已经注意到循环运行了1000万次......这很多。

更新:

我写了另一个基准测试应用程序来模仿你自己:

Module Module1

        Sub Main()

            Dim str As String = ""
            Dim sw As New Stopwatch()

            ' Test 1
            sw.Start()
            For i As Integer = 0 To 100000
                 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
            sw.Stop()
            Console.WriteLine("Old method: " & sw.ElapsedMilliseconds & " ms")
            sw.Reset()

            ' Test 2
            sw.Start()
            For i As Integer = 0 To 100000
                 For j As Integer = -1 To 13
                        str = ComputeLabel_Y(j, False, False)
                        str = ComputeLabel_Y(j, True, False)
                        str = ComputeLabel_Y(j, False, True)
                 Next
            Next
            sw.Stop()
            Console.WriteLine("New method: " & sw.ElapsedMilliseconds & " ms")
            sw.Reset()

        End Sub

        Public Function ComputeLabel_X(ByVal Action As Integer, ByVal Held As Boolean, ByVal Conditional As Boolean) As String
             Dim Prefix As String = ""

             If Conditional Then
                    Prefix = "Conditional "
             ElseIf Held 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

        Public Function ComputeLabel_Y(ByVal Action As Integer, ByVal Held As Boolean, ByVal Conditional As Boolean) As String
             Select Case Action
                    Case 0
                        Return ""
                    Case 1
                        If Conditional Then
                            Return "Conditional Cancelled"
                        ElseIf Held Then
                            Return "Held Cancelled"
                        Else
                            Return "Cancelled"
                        End If
                    Case 2
                        If Conditional Then
                            Return "Conditional Discontinued"
                        ElseIf Held Then
                            Return "Held Discontinued"
                        Else
                            Return "Discontinued"
                        End If
                    Case 3
                        If Conditional Then
                            Return "Conditional Suspended"
                        ElseIf Held Then
                            Return "Held Suspended"
                        Else
                            Return "Suspended"
                        End If
                    Case 4
                        If Conditional Then
                            Return "Conditional Unsuspended"
                        ElseIf Held Then
                            Return "Held Unsuspended"
                        Else
                            Return "Unsuspended"
                        End If
                    Case 6
                        If Conditional Then
                            Return "Conditional Collected"
                        ElseIf Held Then
                            Return "Held Collected"
                        Else
                            Return "Collected"
                        End If
                    Case 7
                        If Conditional Then
                            Return "Conditional Released from Hold"
                        ElseIf Held Then
                            Return "Held Released from Hold"
                        Else
                            Return "Released from Hold"
                        End If
                    Case 8
                        If Conditional Then
                            Return "Conditional Modified"
                        ElseIf Held Then
                            Return "Held Modified"
                        Else
                            Return "Modified"
                        End If
                    Case 9
                        If Conditional Then
                            Return "Conditional Discontinued for the Future"
                        ElseIf Held Then
                            Return "Held Discontinued for the Future"
                        Else
                            Return "Discontinued for the Future"
                        End If
                    Case 10
                        If Conditional Then
                            Return "Conditional Verified"
                        ElseIf Held Then
                            Return "Held Verified"
                        Else
                            Return "Verified"
                        End If
                    Case 11
                        If Conditional Then
                            Return "Conditional Modified And Verified"
                        ElseIf Held Then
                            Return "Held Modified And Verified"
                        Else
                            Return "Modified And Verified"
                        End If
                    Case 12
                        If Conditional Then
                            Return "Hold Conditional Cancelled"
                        ElseIf Held Then
                            Return "Hold Held Cancelled"
                        Else
                            Return "Hold Cancelled"
                        End If
                    Case Else
                        Return ""
             End Select
        End Function
End Module

我的代码再次使我的结果更快:

旧方法:169 ms

新方法:30毫秒

我当然在没有调试的情况下运行(Ctrl F5)。现在我使用的是3.0 GHz AMD四核。

答案 1 :(得分:1)

你不能优化它,它已经非常有效。你可以让它更具可读性,Flag1和Flag2肯定应该重命名为Held和Conditional。

答案 2 :(得分:1)

实际上,如果将它们放入数组中,它会使用以下方法将执行时间从我的机器上的6589ms带到1174ms:

以下是来自控制台应用,但您可以获得一般的想法。数组加载一次,然后根据需要多次访问,在这种情况下,我使用了Steve Wortham发布的for循环作为测试。

Dim _ConditionalLabels(12) As String
Dim _HeldLabels(12) As String

Sub Main()
    Dim sw As New Stopwatch()
    sw.Start()

    _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 10000000
        str = ComputeLabel(0, True, False)
        str = ComputeLabel(1, False, False)
        str = ComputeLabel(0, False, False)
        str = ComputeLabel(2, False, False)
        str = ComputeLabel(1, False, True)
        str = ComputeLabel(2, True, True)
        str = ComputeLabel(4, False, True)
        str = ComputeLabel(7, True, True)
        str = ComputeLabel(12, False, True)
    Next

    sw.Stop()
    Console.WriteLine(sw.ElapsedMilliseconds & " ms")
    Console.Read()
End Sub

Public Function ComputeLabel(ByVal Action As Integer, ByVal Held As Boolean, ByVal Conditional As Boolean) As String
    If Conditional Then
        Return _ConditionalLabels(Action)
    ElseIf Held Then
        Return _HeldLabels(Action)
    End If
End Function

答案 3 :(得分:1)

以下是我自己的速度测试结果(最后)。

在我的测试中,我使用了以下代码。我使用了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 ms(添加边界检查)
  • Erik:614 ms(与Russ相同,但数组填充为数组文字{}而不是单独的语句)
  • Erik2:526 ms(0到12,额外的0到2,没有边界检查)
  • 史蒂夫:660毫秒
  • Steve2:873 ms(删除个别If语句的ElseIf)
  • 新:2977毫秒(我之前回答的第一个想法)
  • 首发:3915毫秒* - 修改为正确(10倍太小)
  • 原文:3947毫秒(您从未见过的版本,我在此优化发布的版本)
  • 选择:11068毫秒
  • BigArray:12565 ms(用数学计算大数组的索引)

尽管较高值的执行时间可能会波动100毫秒,但排名往往保持一致,除了继续交换的Russ和Erik版本。

外卖:

  • 构建数组一次是微不足道的。将其作为单个语句或数组文字{}进行操作是相同的。

  • 对数组方法进行边界检查需要多花费20%。

  • 直观地扩展整个事物似乎应该是最快的,但事实并非如此。我不知道为什么。也许它与处理器缓存行大小和预加载权衡等有关。

  • 我从原始函数到我在问题中发布的函数所做的唯一真正的改变是:1)从每个case语句返回而不是将字符串赋值给变量并在结尾返回(加上删除变量),2)交换独立的If Flag语句顺序并将第二个If更改为ElseIf。 1%的改善是微不足道的

  • 好像我应该可以概括一下我的版本列为“新”(我发布的另一个答案中的第一个查询)这样做的事实。这是更长的字符串吗?是否返回同样快,无论程序在哪里完成,但是从Case语句中删除以执行更多指令的速度很慢?

  • Russ的阵列版本最快。数组查找比带字符串连接的case语句更快。

  • 此时我不知道如何解释为什么新版本更快。

  • 选择功能超级,超级慢。

由于这些测试,我必须将这个问题的答案授予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

现在,如果我犯了另一个错误,有人可以帮忙找到它。

答案 4 :(得分:0)

Steve Wortham已经说过最重要的事情:函数中唯一低效的部分是字符串连接。如果确实需要快速执行该功能,请忽略源代码长度并明确扩展每个案例,这样就可以避免连接字符串。

我想补充一点:使用数组不会帮助您优化功能。 .NET数组不是C数组,它们是复杂的对象,必须构造,填充数据并销毁。

答案 5 :(得分:0)

对这个版本的任何想法?

Public Shared Function ComputeLabel(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

还是这个?

Public Shared Function ComputeLabel(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

我怀疑选择功能可能真的很慢......

我认为原始功能对于维护代码的人来说仍然可能比任何其他选项更清晰。叹息。