Question

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

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?

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.

Was it helpful?

Solution

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.

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

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();
    }
}

Results:

Using return value: 11316
Using out parameter: 7461

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!

OTHER TIPS

Not a performance issue, but something that came up earlier - you can't use them with variance in C# 4.0.

Personally, I tend to use out parameters a fair amount in my private code (i.e. inside a class, having a method that returns multiple values without using a separate type) - but I tend to avoid them on the public API, except for the bool Try{Something}(out result) pattern.

There are no performance implications. out is basically the same as any old argument passing, from a technical point of view. While it might sound plausible that huge amounds of data are copied (e.g. for large structs), this is actually the same as for return values.

In fact, return values for all types > 32 bit are handled similar to out arguments on the machine level anyway.

Please note that the last statement doesn't suggest that returning a value == out parameter in .NET. Jon's benchmark shows that this is obviously (and regrettably) not the case. In fact, to make it identical, named return value optimization is employed in C++ compilers. Something similar could potentially be done in future versions of the JIT to improve performance of returning large structures (however, since large structures are quite rare in .NET, this might be an unnecessary optimization).

However, (and with my very limited knowledge of x86 assembly), returning objects from function calls generally entails allocating sufficient space at the call site, pushing the address on the stack and filling it by copying the return value into it. This is basically the same that out does, only omitting an unnecessary temporary copy of the value since the target memory location can be accessed directly.

The main reason for avoiding out parameters is code readability, rather than performance.

For value types there's no real difference anyway (they always copy) and for reference types it's basically the same as passing by ref.

Nine times out of ten you're better off creating your own dumb record class, rather than using an out parameter - this is simpler to read and understand when you return to the code later.

Out parameters are passed by ref. So only a pointer passed on the stack.

If your value type is large, there is less copy, but then you have to dereference the pointer on each variable use.

Using an out parameter does not hurt performance. An Out parameter is basically a reference parameter, so both the caller and the callee point to the same piece of memory.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top