为什么当我打开C#项目属性>下的“检查算术下溢/溢出”时构建>高级,以下代码比关闭选项(141毫秒)运行得更快(138毫秒)?
测试运行#1:138ms,带有检查算术,141ms没有
- using System;
- using System.Diagnostics;
- class Program
- {
- static void Main(string[] args)
- {
- var s = new Stopwatch();
- s.Start();
- int a = 0;
- for (int i = 0; i < 100000000; i += 3) {
- if (i == 1000)
- i *= 2;
- if (i % 35 == 0)
- ++a;
- }
- s.Stop();
- Console.WriteLine(s.ElapsedMilliseconds);
- Console.WriteLine(a);
- }
- }
另一方面,如果您注释掉if(i == 1000)i * = 2;,则检查的代码比未检查的代码(116 ms)运行得慢(120 ms).
测试运行#2:120ms,116ms没有
- using System;
- using System.Diagnostics;
- class Program
- {
- static void Main(string[] args)
- {
- var s = new Stopwatch();
- s.Start();
- int a = 0;
- for (int i = 0; i < 100000000; i += 3) {
- if (i % 35 == 0)
- ++a;
- }
- s.Stop();
- Console.WriteLine(s.ElapsedMilliseconds);
- Console.WriteLine(a);
- }
- }
进程:重复从PowerShell提示符在Visual Studio外部手动运行.exe,直到结果时间戳保持一致(±1 ms);多次在设置之间翻转以确保一致的结果.
测试盒设置:
> Windows 8.1 Pro x64
> VS2013更新2
>英特尔酷睿i7-4500
>默认C#控制台项目模板
>发布配置
解决方法
答案是你正在处理许多常量,这些常量允许JIT做出安全的假设,它永远不会溢出.如果您使用类似Fibbonacci基准的东西,差异就会变得清晰.
2770ms vs 4150ms(Anycpu,32位首选)
- using System;
- using System.Diagnostics;
- class Program
- {
- static void Main(string[] args)
- {
- var s = new Stopwatch();
- s.Start();
- int a = 0;
- for (int i = 0; i < 100000000; i++)
- {
- a = Fibonacci(45);
- }
- s.Stop();
- Console.WriteLine(s.ElapsedMilliseconds);
- }
- public static int Fibonacci(int n)
- {
- int a = 0;
- int b = 1;
- for (int i = 0; i < n; i++)
- {
- int temp = a;
- a = b;
- // if the JIT compiler is clever,only this one needs to be 'checked'
- b = temp + b;
- }
- return a;
- }
- }