在哪里放一个算术检查语句?

时间:2014-04-09 16:44:54

标签: c# performance math overflowexception

我正在阅读有关如何强制执行操作以抛出溢出异常的问题,并且在#34;自己试试"部分,我把它放在与书不同的地方。我很好奇是否存在与某个地点相关的性能问题,因为我不确定checked关键字的基本机制。

本书中的例子是做一个阶乘,即使使用无符号长整数也会快速抛出溢出。这是我提出的代码:

static long Factorial (long number) {
    long result = 1;

    for (int i = 2; i <= number; i++) {
        checked {
            result *= i;
        }
    }

    return result;
}

但是,查看本书后面的答案页面,他们将checked包裹在函数的整个主体中,包括returnlong result = 1;。显然,你在这些地方永远不需要一个,所以如果有的话,我只需将for循环包裹在check中。

它是否存在于循环内导致一些底层CLR代码重复生成? (就像你在输入for循环之前声明一个变量一样。)或者在循环中没有开销吗?

1 个答案:

答案 0 :(得分:4)

编译结果方面差别不大。

主要区别在于checked块内的任何算术运算都将使用不同的IL指令。没有更多指令,只是不同的指令。不是mul,而是mul.ovf - 而不是add,而是获得add.ovf等。

但是,您的版本实际上的行为略有不同。由于您将checked块放在更大的范围内,因此仍将取消选中变量增量(i++)。原始版本将一直被检查,这意味着i++可以抛出,而不仅仅是乘法运算。这确实意味着您的版本更快,但这只是因为您避免了溢出检查并更改了结果行为,而不是因为范围更改。

  

它是否存在于循环内导致一些底层CLR代码重复生成?

不,它只是意味着该范围内的那些IL指令将获得具有溢出检查的不同IL操作代码而不是标准的。

  

或者循环中是否没有开销?

没有开销(除了指令本身的检查额外开销)。