的try-catch加快我的code? [英] Try-catch speeding up my code?

查看:272
本文介绍了的try-catch加快我的code?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一些code测试的try-catch的影响,但看到了一些令人惊讶的结果。

I wrote some code for testing the impact of try-catch, but seeing some surprising results.

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左右的数值。

On my computer, this consistently prints out a value around 0.96..

当我用这样的try-catch块包裹的循环内黄金分割回调():

When I wrap the for loop inside Fibo() with a try-catch block like this:

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 ... - 实际上它运行速度更快!但是,为什么?

Now it consistently prints out 0.69... -- it actually runs faster! But why?

注:我使用发布配置编译这一点,直接运行EXE文件(Visual Studio中以外)

Note: I compiled this using the Release configuration and directly ran the EXE file (outside Visual Studio).

编辑:全碟的优秀的的分析显示的try-catch由于某种原因造成的x86 CLR在这种特殊情况下使用的CPU寄存器以更有利的方式(我认为我们还没有明白为什么)。本人确认Jon的发现,即64位的CLR不具有此差别,而且它比86的CLR更快。我还测试了使用黄金分割回调方法,而不是类型里面 INT 类型,然后在x86 CLR是作为同样快作为64 CLR。​​

Jon Skeet's excellent analysis shows that try-catch is somehow causing the x86 CLR to use the CPU registers in a more favorable way in this specific case (and I think we're yet to understand why). I confirmed Jon's finding that x64 CLR doesn't have this difference, and that it was faster than the x86 CLR. I also tested using int types inside the Fibo method instead of long types, and then the x86 CLR was as equally fast as the x64 CLR.

更新:它看起来像这个问题已经修复罗斯林。同一台机器,同样的CLR版本 - 的问题仍然是,当用VS 2013编译以上,但问题消失时,与VS 2015年编译

UPDATE: It looks like this issue has been fixed by Roslyn. Same machine, same CLR version -- the issue remains as above when compiled with VS 2013, but the problem goes away when compiled with VS 2015.

推荐答案

其中罗斯林工程师谁在理解堆栈使用的优化看了看这一点,并报告给我,似乎有在C#编译器生成局部变量存储的方式和途径的 JIT 编译器注册的调度在相应的x86 code。其结果是对当地人的载入和存储最理想code一代。

One of the Roslyn engineers who specializes in understanding optimization of stack usage took a look at this and reports to me that there seems to be a problem in the interaction between the way the C# compiler generates local variable stores and the way the JIT compiler does register scheduling in the corresponding x86 code. The result is suboptimal code generation on the loads and stores of the locals.

由于某种原因尚不清楚,对大家,有问题的code生成路径,避免手震知道该块是在try保护的区域。

For some reason unclear to all of us, the problematic code generation path is avoided when the JITter knows that the block is in a try-protected region.

这是pretty的怪异。我们会跟进抖动球队,看看我们是否可以得到一个错误输入,这样可以解决这个问题了。

This is pretty weird. We'll follow up with the JITter team and see if we can get a bug entered so that they can fix this up.

此外,我们正在努力改进罗斯林到C#和VB编译器的算法时,当地人可以由临时决定 - 即,只是压入和弹出堆栈上,而不是分配一个特定的位置栈的激活的持续时间。我们认为,抖动就能做到的寄存器分配一个更好的工作和诸如此类的东西,如果我们给它什么时候当地人可以由死更好的提示前面。

Also, we are working on improvements for Roslyn to the C# and VB compilers' algorithms for determining when locals can be made "ephemeral" -- that is, just pushed and popped on the stack, rather than allocated a specific location on the stack for the duration of the activation. We believe that the JITter will be able to do a better job of register allocation and whatnot if we give it better hints about when locals can be made "dead" earlier.

感谢您将这一对我们的关注,并道歉的古怪行为。

Thanks for bringing this to our attention, and apologies for the odd behaviour.

这篇关于的try-catch加快我的code?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆