3

我正在阅读有关如何强制操作引发溢出异常的信息,在“自己尝试”部分,我将它放在与书不同的地方。我很好奇是否存在与某个位置相关的性能问题,因为我不确定checked关键字的基本机制。

书中的例子是做一个阶乘,它会很快抛出一个溢出,即使是一个无符号长。这是我想出的代码:

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

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

    return result;
}

但是,查看书后的答案页,他们checked将整个函数体都包裹起来,包括returnand long result = 1;。显然你在那些地方永远不需要一个,所以如果有的话,我会把for循环包装在check.

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

4

1 回答 1

4

就编译结果而言,差别不大。

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

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

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

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

还是在循环内没有开销?

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

于 2014-04-09T16:54:08.127 回答