Search code examples
c#.netoptimizationinline

Optimizing the property getter for a ValueType


I have an hierarchical structure of classes like this

public class Class1
{
    internal DateTime time = DateTime.Now;
}

public class Class2
{
    internal Class1 C1;

    public Class2(Class1 c1) { C1 = c1; }

    public DateTime Time { get { return C1.time; } }
}

public class Class3
{
    internal Class2 C2;

    public Class3(Class2 c2) { C2 = c2; }

    public DateTime Time { get { return C2.Time; } }
}

public class Class4
{
    internal Class3 C3;

    public Class4(Class3 c3) { C3 = c3; }

    public DateTime Time { get { return C3.Time; } }
}

I wondered when I call

Class4 C4 = new Class4(.....);  
Console.WriteLine(C4.Time);

will the ValueType data (it is DateTime in this scenario) be copied 4 times or will JIT compiler optimize the code and regenerate it as an inlined version like C4.C3.C2.C1.time;

C# compiler does not do any optimization. ILDASM generated code is here:

// get { return C3.Time; }
.method public hidebysig specialname instance valuetype [mscorlib]System.DateTime 
        get_Time() cil managed
{
  // Code size       12 (0xc)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldfld      class CSTester.Class3 CSTester.Class4::C3
  IL_0006:  callvirt   instance valuetype [mscorlib]System.DateTime CSTester.Class3::get_Time()
  IL_000b:  ret
} // end of method Class4::get_Time

// get { return C2.Time; }
.method public hidebysig specialname instance valuetype [mscorlib]System.DateTime 
        get_Time() cil managed
{
  // Code size       12 (0xc)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldfld      class CSTester.Class2 CSTester.Class3::C2
  IL_0006:  callvirt   instance valuetype [mscorlib]System.DateTime CSTester.Class2::get_Time()
  IL_000b:  ret
} // end of method Class3::get_Time

EDIT: Code is compiled in release mode with optimizations enabled.


Solution

  • Eric Lippert says I don't know much more eloquently than me.

    On a side note,

    int sizeInBytes;
    unsafe
    {
        sizeInBytes = sizeof(DateTime);
    }
    

    results in a value of 8 for me but it would be unsafe to rely on it. The copying of 24 bytes is not worth worrying about. If it is, perhaps a lower generation of language should be used for this part of the code.