-1

this may be a duplicate but I can't find an exact match to my question from the suggestions that came up when asking:

is there a big performance difference, if any, between the following in c#:

var object = new object();
object.propx = x;
object.propy = y;

vs

var object = new object { propx = x, propy = y};
Abdul Ahmad
  • 9,673
  • 16
  • 64
  • 127
  • 2
    A great way to find out would be to test it. My intuition tells me that, depending on the compiler, it would compile into the same IL. – itsme86 Dec 16 '14 at 16:19
  • yes, but I'm not sure how and I'm in the middle of work right now, with a deadline coming in a couple days – Abdul Ahmad Dec 16 '14 at 16:20
  • 3
    @itsme86 - the proper way is to look at IL... but indeed [horses](http://ericlippert.com/2012/12/17/performance-rant/) – Alexei Levenkov Dec 16 '14 at 16:20
  • @AbdulAhmad So this will be a fun little challenge for you after your deadline. – Asad Saeeduddin Dec 16 '14 at 16:21
  • 1
    The latter is just syntactic sugar for the former. – Ben Robinson Dec 16 '14 at 16:21
  • 1
    If you're working towards a deadline, this should be of no concern, unless you actually have performance issues and have that narrowed down to object initializers (the latter of which is nigh impossible). – CodeCaster Dec 16 '14 at 16:23
  • BTW, the explanation is in the specification as highlighted by Eric Lippert in this answer - http://stackoverflow.com/a/2022570/477420 – Alexei Levenkov Dec 16 '14 at 16:24

1 Answers1

1

No, there is no difference, as it results in the same IL.

Compiling the following:

class Program
{
    static void Main(string[] args)
    {
        var objectA = new Test();
        objectA.PropA = 1;
        objectA.PropB = 10;

        var objectB = new Test() { PropA = 2, PropB = 20 };
    }
}

public class Test
{
    public int PropA { get; set; }
    public int PropB { get; set; }
}

Will produce the following IL (release mode):

IL_0000: newobj instance void InitTest.Test::.ctor()
IL_0005: dup
IL_0006: ldc.i4.1
IL_0007: callvirt instance void InitTest.Test::set_PropA(int32)
IL_000c: ldc.i4.s 10
IL_000e: callvirt instance void InitTest.Test::set_PropB(int32)
IL_0013: newobj instance void InitTest.Test::.ctor()
IL_0018: dup
IL_0019: ldc.i4.2
IL_001a: callvirt instance void InitTest.Test::set_PropA(int32)
IL_001f: dup
IL_0020: ldc.i4.s 20
IL_0022: callvirt instance void InitTest.Test::set_PropB(int32)
IL_0027: pop
IL_0028: ret

Both call the setter methods the same way after creating the instance.

Christoph Fink
  • 22,727
  • 9
  • 68
  • 113
  • 1
    It's not *exactly* the same -- there's an extra `dup` for the object initializer. More importantly, however, is that you're not *consuming* the variables at all, and so the fact that object initializers declare an extra variable (because the variable is guaranteed to never have a value that is only part-way initialized) is optimized away. I suggest you add a `Console.WriteLine(objectA)` (or `objectB`) after each instance is initialized and you'll see the object initializer code is noticeably different. Not that you should care about performance here, but there are differences. – Kirk Woll Dec 16 '14 at 17:05
  • @KirkWoll: True - I removed the *exactly*. I also checked it with the access and then all the `dup`s are gone, but the object initializer has an additional `stloc` and `ldloc` (see http://pastebin.com/PrsSdzG8), but I don't know what exactly they are, as I am not "fluent in IL". – Christoph Fink Dec 16 '14 at 17:20
  • You should compare the actual machine language generated by the jitter, not the IL. – Michael Liu Dec 16 '14 at 17:22
  • Basically, `stloc` and `ldloc` is IL-speak for storing and loading local variables. (Though that oversimplifies, since they are often used for variables you don't declare in your code) Case-in-point: object initializer syntax creates the object in one storage location, initializes it, and finally stores it in the final location that represents the variable you declared. This can potentially have subtle semantic ramifications as it means the variable can't be used (perhaps on a different thread) before it is fully initialized. – Kirk Woll Dec 16 '14 at 17:22