繁体   English   中英

C#中算术溢出检查的最佳实践是什么?

[英]What are best practices for arithmetic overflow checking in C#?

关于'checked'关键字与编译器选项'Check for arithmetic overflow / underflow'的使用,web / stackoverflow上有一些很好的文章,如下所示:

http://www.codethinked.com/c-trivia-what-no-overflow

为什么C#默认不使用算术溢出检查?

在C#中处理整数溢出的最佳方法是什么?

我仍然不知道应该使用哪一个。 默认情况下,我更喜欢使用编译器选项来保证安全,不要使用unchecked关键字混乱我的代码,不要忘记它在某些地方,最后它不是很常用,所以许多开发人员可能都不知道。

但是,我采取的实际性能有多糟糕? 我想MS设置默认不进行溢出检查是有充分理由的。 编译器选项是仅涉及我的代码还是每个使用的库和框架本身?

我有同样的问题。 我更喜欢在我公司的代码中默认检查一段代码,因为溢出副作用可能会花费很多而且难以诊断。 发现这些副作用的真正原因可能是每一个有价值的。

问题是,我们在绩效方面会失去什么?

这是一个非常简单的工作台:

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中,我看到checkedunchecked关键字确定是否将使用add.ovfadd指令。 (适用于Debug和Release配置)

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

性能受到影响,看起来选择要检查或取消选中的正确变量类型更为重要。 无论如何,它并没有改变我的观点。 我将在所有项目中打开“检查算术溢出/下溢”! (高级构建设置)。

当需要性能时,我将简单地使用未经检查的块。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM