来自太多错误的错误表现?

时间:2010-04-22 21:19:37

标签: c# performance error-handling

我在C#(.NET 2.0)中有一个大项目,它包含由SubSonic生成的非常大的代码块。像这样的尝试捕获会导致可怕的性能损失吗?

for (int x = 0; x < identifiers.Count; x++)
        {decimal target = 0;
            try
            {
                target = Convert.ToDecimal(assets[x + identifiers.Count * 2]); // target %
            }
            catch { targetEmpty = true;  }}

发生的事情是,如果传入的给定字段不是可以转换为十进制的字段,则会设置一个标志,然后在记录中进一步使用该标志以确定其他内容。

问题是,当我通过30k记录进行解析时,应用程序实际上会抛出数以万计的异常。整个过程花了将近10分钟来完成所有事情,我的总体任务是改善一些时间,如果这是一个糟糕的设计理念,这似乎很容易挂起。

任何想法都会有所帮助(善良,这是悲惨的一天)

感谢, 克里斯

4 个答案:

答案 0 :(得分:5)

使用控制流的异常通常是一种不好的做法(正是因为你观察到的效率很低)。您需要将哪种类型的数据转换为decimal?如果输入不是预期的格式,你可以使用TryParse方法或其他不抛出异常的方法吗?

如果您正在解析字符串,那么

Decimal.TryParse method应该可以解决问题,因为它通过返回false来报告失败:

decimal d;
if (Decimal.TryParse(str, out d)) 
  // Ok, use decimal 'd'
else 
  // Failed - do something else

答案 1 :(得分:4)

这是一段真正可怕的代码。通常,异常仅应用于捕获意外结果。您获得大量异常的事实意味着这是一个应该成为内在逻辑的一部分的常见条件。

decimal.TryParse在这里是一个更好的选择,我建议缓存identifiers.Count * 2的值(不确定编译器是否会优化它)

答案 2 :(得分:3)

还有一个TryParse的Decimal。它避免了异常并使用bool来表示成功/失败。

答案 3 :(得分:0)

这是一个可怕的代码,你会得到关于如何解决它的好建议。

如果你想知道这些例外是否花费了你很大一部分时间,那么有一个简单的方法可以找到答案。

暂停大约10次,每次都检查一下调用堆栈。如果异常花费了一定比例的时间,例如50%,那么你将在大致相当于暂停的百分比上抛出或捕捉它们。