我写了一些代码来测试try-catch的影响,但看到了一些令人惊讶的结果。
static void Main(string[] args){Thread.CurrentThread.Priority = ThreadPriority.Highest;Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.RealTime;
long start = 0, stop = 0, elapsed = 0;double avg = 0.0;
long temp = Fibo(1);
for (int i = 1; i < 100000000; i++){start = Stopwatch.GetTimestamp();temp = Fibo(100);stop = Stopwatch.GetTimestamp();
elapsed = stop - start;avg = avg + ((double)elapsed - avg) / i;}
Console.WriteLine("Elapsed: " + avg);Console.ReadKey();}
static long Fibo(int n){long n1 = 0, n2 = 1, fibo = 0;n++;
for (int i = 1; i < n; i++){n1 = n2;n2 = fibo;fibo = n1 + n2;}
return fibo;}
在我的电脑上,这始终打印出0.96左右的值。
当我在Fibo()中包装for循环时,使用像这样的try-catch块:
static long Fibo(int n){long n1 = 0, n2 = 1, fibo = 0;n++;
try{for (int i = 1; i < n; i++){n1 = n2;n2 = fibo;fibo = n1 + n2;}}catch {}
return fibo;}
现在它始终打印出0.69…--它实际上运行得更快!但是为什么呢?
注意:我使用发布配置编译了它并直接运行EXE文件(在Visual Studio之外)。
编辑:Jon Skeet的优秀分析表明,在这种特定情况下,try-catch以某种方式导致x86 CLR以更有利的方式使用CPU寄存器(我认为我们还不明白为什么)。我证实了Jon的发现,x64 CLR没有这种差异,而且它比x86 CLR快。我还在Fibo方法中使用int
类型而不是long
类型进行了测试,然后x86 CLR和x64 CLR一样快。
更新:看起来Roslyn已经修复了这个问题。相同的机器,相同的CLR版本——使用VS 2013编译时问题仍然如上所述,但使用VS 2015编译时问题消失了。