【问题标题】:Try ... Catch : Performance尝试...抓住:性能
【发布时间】:2019-02-23 12:05:54
【问题描述】:

我有一个将数字转换为 N 基数的代码示例。
我可以有 2、3 或 4 位数字。

我的功能有效,看起来像这样:

Private Function BaseN(s As String)
    Dim d = Val(s(s.Length - 1))
    Dim c = Val(s(s.Length - 2))
    Dim a, b As Integer
    Try
        b = Val(s(s.Length - 3))
    Catch
        b = 0
    End Try
    Try
        a = Val(s(s.Length - 4))
    Catch
        a = 0
    End Try

    Return (a * (n * n * n) + b * (n * n) + c * n + d + 1).ToString
End Function

但出于某种原因,转换我的文本需要大约 10 秒。

我试过这样:

Private Function BaseN(s As String)
    Dim d = Val(s(s.Length - 1))
    Dim c = Val(s(s.Length - 2))
    Dim a, b As Integer
        b = 0
        a = 0

    Return (a * (n * n * n) + b * (n * n) + c * n + d + 1).ToString
End Function

这里的转换大致是即时的。

所以我想知道为什么 try catch 运行时间如此之长,或者我对它们的使用不当。

【问题讨论】:

  • 第二个函数有一半的Vals,不清楚你是否正在运行发布版本。如果在第一个函数中 Trys 实际在每一行输入上触发,那么是的,它可能会明显变慢,而你 should not do that
  • 抛出和捕获异常代价高昂,因此只能在特殊情况下进行。你的情况绝对不是这样。不要对控制流使用异常。如果要获取子字符串,请先确保 String 足够长。预防胜于治疗。不要做错事,事后清理。在做之前确保你做的是正确的事情。
  • 谢谢,这就是我想知道的。我虽然将尝试用作“IF ERROR THEN ...”的用法很好,但这就是我尝试的原因。如果那样的话,我会做一个简单的
  • @GSerg 很好的链接。谢谢。
  • 附带说明,Val 是一个遗留函数,由于其各种怪癖,即使在经典的 VB 代码中也被怀疑使用。我强烈建议不要使用它。 Mary 的回答提供了一个很好的选择(如果您需要使用浮点数而不是整数,还有一个 Double.TryParse)。

标签: vb.net performance try-catch


【解决方案1】:

仅仅因为您没有使用 Try...Catch 捕获错误并不意味着您不必考虑虚假的用户输入。以下代码应通过检查输入的整数和字符串长度来避免崩溃。

Integer.TryParse(string, integerVariable) 将检查字符串是否可以转换为整数。它用字符串的整数表示填充 integerVariable。 integerVariable 即使失败也将为零,这使您的最终方程式有效。

我没有检查函数本身的有效性。

Private Function BaseN(s As String, n As Integer) As String
    Dim StringLength As Integer = s.Length
    Dim a, b, c, d As Integer
    Select Case StringLength
        Case 2
            Integer.TryParse(s(StringLength - 1), d)
            Integer.TryParse(s(StringLength - 2), c)
        Case 3
            Integer.TryParse(s(StringLength - 3), b)
            Integer.TryParse(s(StringLength - 1), d)
            Integer.TryParse(s(StringLength - 2), c)
        Case 4
            Integer.TryParse(s(StringLength - 4), a)
            Integer.TryParse(s(StringLength - 3), b)
            Integer.TryParse(s(StringLength - 1), d)
            Integer.TryParse(s(StringLength - 2), c)
        Case Else
            Return ""
    End Select
    Return (a * (n * n * n) + b * (n * n) + c * n + d + 1).ToString
End Function

【讨论】:

  • 此代码忽略来自TryParse 的返回值。如果字符串的任何字符不是数字,则此代码可能会返回不正确的值。
  • @ChrisDunaway OP 将零分配给未通过 Val 测试的变量,这正是我的代码中发生的情况。
猜你喜欢
  • 1970-01-01
  • 2011-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-25
  • 1970-01-01
相关资源
最近更新 更多