C# out 参数性能 [英] C# out parameter performance

查看:26
本文介绍了C# out 参数性能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C# 中的 out 参数是否有任何我应该知道的性能影响?(如例外)

Do out parameters in C# have any performance implications I should know about? (Like exceptions)

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

I mean, is it a good idea to have a method with an out parameter in a loop that will run a couple of million times a second?

我知道它很丑,但我使用它的方式与 Int32.TryParse 使用它们的方式相同 - 返回一个 bool 来判断某些验证是否成功并有一个out 参数包含一些成功的附加数据.

I know it's ugly but I am using it the same way as Int32.TryParse is using them - returning a bool to tell if some validation was successful and having an out parameter containing some additional data if it was successful.

推荐答案

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

I doubt that you'll find any significant performance penalty to using an out parameter. You've got to get information back to the caller somehow or other - out is just a different way of doing it. You may find there's some penalty if you use the out parameter extensively within the method, as it may well mean an extra level of redirection for each access. However, I wouldn't expect it to be significant. As normal, write the most readable code and test whether performance is already good enough before trying to optimise further.

其余部分是有效的.它只与大值类型真正相关,无论如何通常应该避免:)

The rest of this is an aside, effectively. It's only really relevant for large value types, which should usually be avoided anyway :)

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

I disagree with Konrad's assertion about "return values for all types > 32 bit are handled similar or identical to out arguments on the machine level anyway" though. Here's a little test app:

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 参数,我们将数据直接写入最终目的地,而不是将其写入小方法的堆栈帧,然后将其复制回 Main 方法的堆栈帧.

Basically by using an out parameter we're writing the data directly to the final destination, rather than writing it to the small method's stack frame and then copying it back into the Main method's stack frame.

请随意批评基准测试应用程序 - 我可能错过了一些东西!

Feel free to criticise the benchmark app though - I may have missed something!

这篇关于C# out 参数性能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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