2

I have been trying to optimize the performance of access to a time-critical class. When I measured, I was surprised to find a significant difference in performance between Member access and Property access. See example below:

using System;
using System.Diagnostics;

public class ClassSample {
    public static int StaticField = 0;
    public int InstanceMember = 0;
    public int PropertyField { get; set; }
    public ClassSample() {
        PropertyField = 0;
    }
}

public class Program {
    public static void Main(string[] arg) {
        var obj = new ClassSample();
        int N = 10000000;
        Stopwatch sp = new Stopwatch();
        sp.Start();
        int total = 0;
        for (int i = 0; i < N; i++) {
            ClassSample.StaticField = i;
            total += ClassSample.StaticField;
        }
        sp.Stop();
        Console.Out.WriteLine("Static  :\t" + sp.Elapsed);
        sp.Restart();

        total = 0;
        for (int i = 0; i < N; i++) {
            obj.InstanceMember = i;
            total += obj.InstanceMember;
        }
        sp.Stop();
        Console.Out.WriteLine("Member:  \t" + sp.Elapsed);
        sp.Restart();

        total = 0;
        for (int i = 0; i < N; i++) {
            obj.PropertyField = i;
            total += obj.PropertyField;
        }
        sp.Stop();
        Console.Out.WriteLine("Property:\t" + sp.Elapsed);
    }
}

Where I run this (.Net 4.5/Windows 10), I get these results:

Static  :       00:00:00.0243832
Member:         00:00:00.0240386 
Property:       00:00:00.0624915

So the Property access is more than twice slower than the others. Is this expected? Any way to avoid it?

kristianp
  • 5,496
  • 37
  • 56
Alex Schmidt
  • 39
  • 1
  • 3
  • 4
    Please, read [this](http://stackoverflow.com/questions/1047218/benchmarking-small-code-samples-in-c-can-this-implementation-be-improved) first. – Anton Gogolev Aug 25 '16 at 14:09
  • I cannot reproduce your results. Either there is something weird going on with your system, or you missed something obvious like testing in debug mode or with a debugger attached. – HugoRune Aug 25 '16 at 14:15
  • 1
    Yep. When running in Release mode it works well. – Alex Schmidt Aug 25 '16 at 14:22

3 Answers3

4

I have experienced this as well, but I figured out later that, if you optimize your Release target properly, the Property access is optimized by the compiler to a point that it is equal in performance to the member access. Give it a try and run the Release target, you should see a marked improvement. It seems like most of the difference has to do mostly with running in Debug.

1

Properties are basically special methods. Calling a method has more overhead than reading the value of a field.

Did you build your performance test in Debug mode? When build in Release mode the compiler inlines trivial property getters/setters and should make properties perform roughly the same as fields.

Wazner
  • 2,962
  • 1
  • 18
  • 24
0
int Property{get; set;}

Is the same as

private int property; 
public int GetProperty(){...} 
public void SetProperty(int value){...}

I would guess that the method overhead makes it slower.

Djeurissen
  • 377
  • 5
  • 15