3

Is there a performance penalty when using an extra local variable to store a method's result?

public string void ToFunkyDutchDate(DateTime this theDate) {
    var result = string.Format("{0:dd-MM-yyyy}", theDate);
    return result;
}

In similar trivial cases I could even tend to return the formatted string immediately. But this is just a simple example, because in a little more complex functions I often use this 'trick' of assigning the result to a temporary local variable first.

My main reason for this is that this allows easier debugging. I can just put a breakpoint on the return result; line, run and inspect if the result my function came up with is correct.

But the extra temporary result variable still feels a bit like unperformant then the alternative without:"

public static string ToFunkyDutchDate(DateTime this theDate) {
    return string.Format("{0:dd-MM-yyyy}", theDate);
}

I have eased this nagging feeling in three ways:

  • Any performance decrease would be negligable
  • Having a variable like result makes the code a bit more legible then return very long multi-line expression, which is worse any performance decrease
  • If C-sharp's compiler was anywhere decent - which I think it is - then it SHOULD compile the extra variable away. E.g. make the resultant bytecode the exact same as if the function just returned the calculated result immediately without using a temporary variable. Either immediately (when not running in debug mode) - or perhaps when doing an optimized/production build (/optimize+).

But I've done this for so many years now, on so many lines of code, I thought I'd just finally ask it. Any compiler wizards here that know? :)

Edit: An answer within a minute to a question that had simmered for years. How great is Stackoverflow. Great tool: http://tryroslyn.azurewebsites.net/

Bart
  • 5,065
  • 1
  • 35
  • 43
  • 7
    I don't think so. Because in this case it should be optimized away. The easiest way to check would be to write it both ways and comparing the resulting IL. – CaffGeek Mar 17 '16 at 15:53
  • 1
    If you look at the IL you'll know what the compiler do. – lnu Mar 17 '16 at 15:54
  • 1
    Even if there was, it's the kind of difference that would be very hard to see. It's going to be entirely dwarfed by the `string.Format` itself, for one :) You need to keep perspective in mind when considering potential performance issues. – Luaan Mar 17 '16 at 15:55
  • 4
    "I haven't actually tested this code example": perhaps you should. – Richard Mar 17 '16 at 15:58
  • 2
    If you want to see the value of the return from a function, put a break point on the closing brace. VS shows the return value. – Richard Mar 17 '16 at 15:58
  • Great Richard! I'll use that! Tools to the rescue. I actually looked for that, because I have occasionally seen a popup with result flying by, but didn't know how to reproduce :). I removed the comment about 'haven't tested' because it now compiles.. thanks. – Bart Mar 17 '16 at 16:02
  • Thanks @Luaan. This was just an example. But I've done this for so many years now, on so many lines of code, I thought I'd just finally ask it. – Bart Mar 17 '16 at 16:04
  • @Richard unfortunately your 'put break point in the closing brace' [does not work in VS 2015](http://stackoverflow.com/questions/268048/can-i-find-out-the-return-value-before-returning-while-debugging-in-visual-studi). At least not in the community edition: – Bart Mar 21 '16 at 18:56

2 Answers2

10

Normally no speed difference. See for example http://goo.gl/b9856y and http://goo.gl/WfIhmT

Both versions of the code produce the same IL code in Release mode.

In Debug mode the IL code is a little longer (because the store to a local variable is made explicit): http://goo.gl/KCkORV

xanatos
  • 109,618
  • 12
  • 197
  • 280
3

I've just ran the two methods through LinqPad and looking at the IL that it provides there is change of two instructions:

With the unused variable:

IL_0000:  ldstr       "{0:dd-MM-yyyy}"
IL_0005:  ldarg.0     
IL_0006:  box         System.DateTime
IL_000B:  call        System.String.Format
IL_0010:  stloc.0     // result
IL_0011:  ldloc.0     // result
IL_0012:  ret         

Directly returning the result of the string.Format:

IL_0000:  ldstr       "{0:dd-MM-yyyy}"
IL_0005:  ldarg.0     
IL_0006:  box         System.DateTime
IL_000B:  call        System.String.Format
IL_0010:  ret        

Would these two extra calls be a performance issue, unlikely, but it's tough for me to say I don't know how critical this area is.

Stephen Ross
  • 882
  • 6
  • 21
  • If your method is called 200 times per second (it could be part of a Service call), then it would matter. – fahadash Aug 20 '18 at 20:01