Home > Software engineering >  C# get class member result caching
C# get class member result caching

Time:07-19

Does C# cache the value for a class member if the result doesn't change? So does C# store the value for Area after it is calculated and simply return it as long as X and Y aren't changed or does the first example calculate X * Y for each Area get call? Or in other words, are the examples below equally (from a computational view point) performant?

public double Area => X * Y;
private double X { get; set; } = 5;
private double Y { get; set; } = 5;

public double Area { get; }

public Rectangle(double x = 5, double y = 5)
{
   Area = x * y;   
}

CodePudding user response:

You can just check the IL code generated by your class.

https://sharplab.io/#v2:C4LglgNgNAJiDUAfAAgJgIwFgBQyDMABGgQMIEDeOB1RhMA9gK4BGEApgQIIBObAhgQC8APgIANAgCoCATQDcVGgAduYAG59gHBi3biKBAOZtgcggGcTZgL5CCAVgXYaBFes3amrDjIPHTFlYEtoIOTi74pAAUOt4EAB5QBLF6AJ4AlBSKLtQSofHhOdS oamF1NY41kA===

Class:

public class C {
    public double Area => X * Y;
    private double X { get; set; } = 5;
    private double Y { get; set; } = 5;
    public C(double x, double y) {
        X = x;
        Y = y;
    }
}

Generated IL code for Area:

  .method public hidebysig specialname 
        instance float64 get_Area () cil managed 
    {
        // Method begins at RVA 0x2050
        // Code size 14 (0xe)
        .maxstack 8

        IL_0000: ldarg.0
        IL_0001: call instance float64 C::get_X()
        IL_0006: ldarg.0
        IL_0007: call instance float64 C::get_Y()
        IL_000c: mul
        IL_000d: ret
    } // end of method C::get_Area

And as you can see - 2 getters are called and mul multiplication call is executed.

You can also take a look at JIT Asm part at the same link. And basically no, no cache will be injected for that property, in this case it depends on the runtime. Runtime might apply some performance optimizations but that will not be the case.

If you convert Area to getter and assign a value to it in constructor - yes, it will require less instructions for reading.

    .method public hidebysig specialname 
        instance float64 get_Area () cil managed 
    {
        .custom instance void [System.Runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
            01 00 00 00
        )
        // Method begins at RVA 0x2050
        // Code size 7 (0x7)
        .maxstack 8

        IL_0000: ldarg.0
        IL_0001: ldfld float64 C::'<Area>k__BackingField'
        IL_0006: ret
    } // end of method C::get_Area
  • Related