C# out 参数性能 [英] C# out parameter performance
问题描述
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屋!