待办事项的退出在参数 C#有任何性能影响我应该知道的? (像例外)

我的意思是,它是一个好主意,有一个循环的out参数,将运行一对夫妇的第二个百万次的方法?

我知道这是丑陋的,但我使用它的方式Int32.TryParse同样是使用它们 - 返回bool说,如果一些验证是成功的,具有包含一些额外的数据,如果它是成功的out参数

有帮助吗?

解决方案

我怀疑你会发现任何显著性能损失使用out参数。你一定要得到的信息返回给调用者以某种方式或其他 - out只是做不同的方式。您可能会发现还有的一些的罚款,如果你使用了大量参数的方法中,因为它可能意味着重定向的每个接入一个额外的水平。不过,我不希望它是显著。为正常,写最可读的代码和测试性能是否已经试图进一步优化之前足够好的

编辑:这样做的其余部分是一个的一边有效。这只是对于大值类型,通常应避免这确实不相干:)

我不同意康拉德的约虽然“为所有类型的> 32位的处理类似或相同出参数对计算机级别反正返回值”断言。这里有一个小的测试程序:

using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;

struct BigStruct
{
    public Guid guid1, guid2, guid3, guid4;
    public decimal dec1, dec2, dec3, dec4;
}

class Test
{
    const int Iterations = 100000000;

    static void Main()
    {
        decimal total = 0m;
        // JIT first
        ReturnValue();
        BigStruct tmp;
        OutParameter(out tmp);

        Stopwatch sw = Stopwatch.StartNew();
        for (int i=0; i < Iterations; i++)
        {
            BigStruct bs = ReturnValue();
            total += bs.dec1;
        }
        sw.Stop();
        Console.WriteLine("Using return value: {0}",
                          sw.ElapsedMilliseconds);

        sw = Stopwatch.StartNew();
        for (int i=0; i < Iterations; i++)
        {
            BigStruct bs;
            OutParameter(out bs);
            total += bs.dec1;
        }
        Console.WriteLine("Using out parameter: {0}",
                          sw.ElapsedMilliseconds);
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    public static BigStruct ReturnValue()
    {
        return new BigStruct();
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    public static void OutParameter(out BigStruct x)
    {
        x = new BigStruct();
    }
}

结果:

Using return value: 11316
Using out parameter: 7461

通过使用我们直接写入数据到最终目的地,而不是将其写入到小方法的堆栈帧,然后将其复制回主方法的堆栈帧的输出参数基本上

随意批评,虽然基准程序 - !我可能错过了一些东西。

其他提示

不是性能问题,而是想出了前面的东西 - 的你不能用方差在C#4.0 使用它们。

我个人倾向于使用out参数相当数量在我的私有代码(即一类的内部,具有返回多个值,而无需使用单独的类型的方法) - 但我倾向于避免他们在公共API,除了bool Try{Something}(out result)图案。

有没有性能影响。 out是基本相同,任何旧的参数传递,从技术角度来看。虽然它可能听起来似乎可能数据的巨大amounds被复制(例如,对于大结构),这是实际上是相同的,作为返回值。

在事实上,对于所有类型的> 32位的处理类似于out上的机水平反正。

请注意,最后的陈述并不表明返回值==在.NET out参数。乔恩的基准测试显示,这是明显的(很遗憾),情况并非如此。事实上,使其相同,命名返回值优化被用在C ++编译器。同样的事情也可能在JIT的未来版本中加以改善返回大型结构的性能(但是,由于大型结构在.NET中相当罕见,这可能是不必要的优化)。

然而,(并与我的非常有限的x86汇编的知识),从函数返回对象调用通常需要在调用位置分配足够的空间,在堆栈上推地址和通过复制填充它返回值到它。这是基本相同的是out做,仅省略该值的不必要的临时副本,因为目标存储位置可被直接访问。

用于避免出参数的主要原因是代码的可读性,而不是性能。

有关的值类型也没有真正的区别反正(他们总是复制)和引用类型是基本相同的由参考传递。

十次有九次,你最好创建自己的愚蠢记录类,而不是使用out参数 - 这是简单的阅读和理解,当你回到后面的代码

缺货参数由REF通过。因此,只有一个指针传递堆栈上。

如果你的价值类型为大,有拷贝少,但你必须取消引用每个变量使用指针。

使用一个输出参数不损害性能。 Out参数基本上是一个参考参数,所以无论是主叫用户和被叫指向同一块内存。

scroll top