c# - 用作控制流机制的异常在某些特定场景下是否有效?

标签 c# .net exception-handling

我正在调整 RationalNumber 实现中的一些代码。特别是,在相等逻辑内部,我正在考虑以下内容:

public bool Equals(RationalNumber other)
{
   if (RationalNumber.IsInfinity(this) ||
       RationalNumber.IsInfinity(other) ||
       RationalNumber.IsNaN(this) ||
       RationalNumber.IsNaN(other))
   {
       return false;
   }

   try
   {
       checked
       {
           return this.numerator * other.Denominator == this.Denominator * other.numerator;
       }
   }
   catch (OverflowException)
   {
       var thisReduced = RationalNumber.GetReducedForm(this);
       var otherReduced = RationalNumber.GetReducedForm(other);
       return (thisReduced.numerator == otherReduced.numerator) && (thisReduced.Denominator == otherReduced.Denominator);
   }
}

如您所见,我使用异常作为流程控制机制。这背后的原因是,我不想在每次相等性检查时计算两个分数的最大公约数时受到惩罚。因此,我只决定在可能性最小的情况下这样做:一个或两个叉积溢出。

这是一种可接受的做法吗?我一直读到异常不应该用作代码的流机制,但我真的没有看到另一种方法来实现我想要的。

欢迎任何替代方法。

最佳答案

The reasoning behind this is that I do not want to incur in the penalty of evaluating the greatest common divisor of both fractions on every equality check.

这是合理的推理。这段代码的总成本是

{probability of fast-path} * {fast-path cost}
+ ((1.0 - {probability of fast-path}) * {slow-path cost})

根据所涉及的三个常量,这是一个好的或坏的选择。您需要充分了解将在实践中处理的数据。

请注意,异常非常慢。我曾经将它们作为每个 CPU 内核每秒 10000 次的基准测试,但由于涉及内部 CLR 锁,我不确定它们是否会扩展到多个内核。

也许您可以添加运行时分析。跟踪异常发生率。如果太高,请关闭优化。

您可能应该记录下您这样做的原因。

这也不是架构问题,因为如果您稍后改变主意,您可以轻松切换到不同的算法。

作为替代方案,您可以先不加检查地进行计算和比较。如果结果“不等于”,则可以保证确切的结果也“不等于”。即使发生溢出。因此,如果许多数字结果不相等,这可能是一条无异常的快速路径。

关于c# - 用作控制流机制的异常在某些特定场景下是否有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31073824/

相关文章:

c# - 处理横切问题,例如 Web 应用程序组件的内部统计报告

c# - 无法使用 ClientScript.RegisterStartupScript 引发 div

c# - 检查浏览器是否接受 cookie

c# - 如何从整数值中获取月份名称?

.net - NetSuite API 创建订单时出错

c# - odp.net 日期时间.MaxDate

c# - 是否可以向上抛出异常

c# - 如何使用 Web 平台安装程序为 Web 应用程序创 build 置

java - java异常会终止整个java应用程序吗?

ruby-on-rails - 处理嵌套关系 rails 2.3.x 中的 nil(空)值