当前位置:  开发笔记 > 编程语言 > 正文

C#输出参数性能

如何解决《C#输出参数性能》经验,为你挑选了3个好方法。

出来的参数C#有任何性能影响我应该知道的?(像例外)

我的意思是,out在循环中使用一个参数的方法是一个好主意,每秒运行几百万次?

我知道它很丑,但我使用它的方式与Int32.TryParse使用它们相同- 返回一个bool告诉我是否有一些验证是成功的,并且如果成功则有一个out包含一些额外数据的参数.



1> Jon Skeet..:

我怀疑你会发现使用out参数有任何显着的性能损失.你必须以某种方式将信息反馈给调用者 - out这只是一种不同的方式.如果在方法中广泛使用out参数,您可能会发现存在一些损失,因为它可能意味着每次访问都需要额外的重定向级别.但是,我不认为它会很重要.正常情况下,编写最易读的代码并在尝试进一步优化之前测试性能是否已经足够好.

编辑:其余部分是有效的.它只适用于大值类型,通常应该避免使用:)

我不同意Konrad的断言,"所有类型的返回值> 32位的处理方式与机器级别的out参数相似或相同"但是.这是一个小测试应用程序:

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

基本上通过使用out参数,我们将数据直接写入最终目标,而不是将其写入small方法的堆栈帧,然后将其复制回Main方法的堆栈帧.

尽管如此批评基准应用程序 - 我可能错过了一些东西!



2> Konrad Rudol..:

没有性能影响.out从技术角度来看,与任何旧的论证基本相同.虽然复制大量数据可能听起来似乎有道理(例如对于大型结构),但这实际上与返回值相同.

事实上,所有类型> 32位的返回值的处理方式与机器级别的out参数类似.

请注意,最后一条语句并不建议out在.NET 中返回value == 参数.Jon的基准测试显示,这显然(并且令人遗憾)并非如此.实际上,为了使它相同,在C++编译器中使用了命名返回值优化.类似的东西可能会在JIT的未来版本中完成,以提高返回大型结构的性能(但是,由于.NET中的大型结构非常少见,这可能是一种不必要的优化).

但是,(并且由于我对x86程序集的知识非常有限),从函数调用返回对象通常需要在调用站点分配足够的空间,推送堆栈上的地址并通过将返回值复制到堆栈中来填充它.这与基本相同out,只是省略了值的不必要的临时副本,因为可以直接访问目标内存位置.



3> Marc Gravell..:

这不是一个性能问题,而是早先出现的问题 - 你不能在C#4.0中使用它们.

就个人而言,我倾向于out在我的私有代码中使用相当大的参数(即在一个类中,有一个方法可以返回多个值而不使用单独的类型) - 但我倾向于在公共API上避免它们,除了bool Try{Something}(out result)模式.

推荐阅读
手机用户2502852037
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有