网络/stackoverflow 上有一些关于“checked”关键字与编译器选项“Check for arithmetic overflow/underflow”用法的好文章,例如:
http://www.codethinked.com/c-trivia-what-no-overflow
Why doesn't C# use arithmetic overflow checking by default?
Best way to handle Integer overflow in C#?
我仍然不知道应该使用哪一个。默认情况下,我更愿意使用编译器选项以确保始终安全,不要让 unchecked 关键字使我的代码困惑,不要在某些地方忘记它,最后它不是很常用,所以很多开发人员可能不知道。
但是我所承受的实际性能损失有多严重?我想 MS 设置默认不进行溢出检查是有充分理由的。编译器选项是否只涉及我的代码或每个使用的库和框架本身?
最佳答案
我也有同样的疑问。我更喜欢在我公司的代码中默认检查一段代码,因为溢出副作用会花费很多并且难以诊断。发现这些副作用的真正原因非常有值(value)。
问题是,我们在性能方面损失了什么?
这是一个非常简单的工作台:
static void Main(string[] args)
{
long c = 0;
var sw = new Stopwatch();
sw.Start();
unchecked
{
for (long i = 0; i < 500000000; i++) c += 1;
}
sw.Stop();
Console.WriteLine("Unchecked: " + sw.ElapsedMilliseconds);
c = 0;
sw.Restart();
checked
{
for (long i = 0; i < 500000000; i++) c += 1;
}
sw.Stop();
Console.WriteLine("Checked: " + sw.ElapsedMilliseconds);
}
在生成的 IL 中,我看到 checked 和 unchecked 关键字决定了 add.ovf 还是 add将使用 strong> 指令。 (用于调试和发布配置)
IL_001c: ldloc.2
IL_001d: ldc.i4.1
IL_001e: conv.i8
IL_001f: add
IL_0066: ldloc.2
IL_0067: ldc.i4.1
IL_0068: conv.i8
IL_0069: add.ovf
结果(x64 主机)
调试
- 未选中:2371
- 检查:2437
发布
- 未选中:2088
- 检查:2266
用 int(s) 替换 long(s) 的其他结果(x64 主机)
调试
- 未选中:1665
- 检查:1568
发布
- 未选中:189
- 已检查:566
性能受到影响,看起来选择正确的变量类型比选中或不选中更重要。无论如何,这不会改变我的看法。我将在我们所有的项目中打开“检查算术溢出/下溢”! (高级build设置)。
当需要性能时,我会简单地使用一个unchecked block 。
关于c# - C# 中算术溢出检查的最佳实践是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19225535/