Search code examples
c#performancepropertiessetterobject-initialization

Setting properties via object initialization or not: Any difference?


Is there any (performance) difference between this:

Person person = new Person()
{
  Name = "Philippe",
  Mail = "[email protected]",
};

and this:

Person person = new Person();
person.Name = "Philippe";
person.Mail = "[email protected]";

You can imagine a bigger object with more properties.


Solution

  • They are almost exactly equivalent except that the first method (using an object initializer) only works in C# 3.0 and newer. Any performance difference is only minor and not worth worrying about.

    They produce almost identical IL code. The first gives this:

    .method private hidebysig instance void ObjectInitializer() cil managed
    {
        .maxstack 2
        .locals init (
            [0] class Person person,
            [1] class Person <>g__initLocal0)
        L_0000: newobj instance void Person::.ctor()
        L_0005: stloc.1 
        L_0006: ldloc.1 
        L_0007: ldstr "Philippe"
        L_000c: callvirt instance void Person::set_Name(string)
        L_0011: ldloc.1 
        L_0012: ldstr "[email protected]"
        L_0017: callvirt instance void Person::set_Mail(string)
        L_001c: ldloc.1 
        L_001d: stloc.0 
        L_001e: ldloc.0 
        L_001f: callvirt instance string [mscorlib]System.Object::ToString()
        L_0024: pop 
        L_0025: ret 
    }
    

    The second gives this:

    .method private hidebysig instance void SetProperties() cil managed
    {
        .maxstack 2
        .locals init (
            [0] class Person person)
        L_0000: newobj instance void Person::.ctor()
        L_0005: stloc.0 
        L_0006: ldloc.0 
        L_0007: ldstr "Philippe"
        L_000c: callvirt instance void Person::set_Name(string)
        L_0011: ldloc.0 
        L_0012: ldstr "[email protected]"
        L_0017: callvirt instance void Person::set_Mail(string)
        L_001c: ldloc.0 
        L_001d: callvirt instance string [mscorlib]System.Object::ToString()
        L_0022: pop 
        L_0023: ret 
    }
    

    As you can see, nearly identical code is generated. See below for the exact C# code I compiled.

    Performance measurements show very similar results with a very small performance improvement for using the object initializer syntax:

    Method               Iterations per second
    ObjectInitializer    8.8 million
    SetProperties        8.6 million
    

    Code I used for testing the performance:

    using System;
    
    class Person
    {
        public string Name { get; set; }
        public string Mail { get; set; }
    }
    
    class Program
    {
        private void ObjectInitializer()
        {
            Person person = new Person()
            {
                Name = "Philippe",
                Mail = "[email protected]",
            };
            person.ToString();
        }
    
        private void SetProperties()
        {
            Person person = new Person();
            person.Name = "Philippe";
            person.Mail = "[email protected]";
            person.ToString();
        }
    
        private const int repetitions = 100000000;
    
        private void Time(Action action)
        {
            DateTime start = DateTime.UtcNow;
            for (int i = 0; i < repetitions; ++i)
            {
                action();
            }
            DateTime end = DateTime.UtcNow;
            Console.WriteLine(repetitions / (end - start).TotalSeconds);
        }
    
        private void Run()
        {
            Time(ObjectInitializer);
            Time(SetProperties);
            Console.WriteLine("Finished");
            Console.ReadLine();
        }
    
        private static void Main()
        {
            new Program().Run();
        }
    }