I am asking this after I have seen some questions and answers about properties and auto properties and how these are represented by the compiler.
From what I understood, an auto-property is represented as a field, with two methods, a getter an a setter. In this case if a field is used, the code to access that field should be faster than the code which accesses a property, because it avoids any suplimentar call to methods. In order to prove this theory I was writing the following code, and please, excuse me for how it looks:
public class A
{
public int Prop { get; set; }
public int Field;
public A()
{
Prop = 1;
Field = 1;
}
}
class Program
{
static void Main(string[] args)
{
List<long> propertyExecutionTimes = new List<long>();
List<long> fieldExecutionTimes = new List<long>();
A a = new A();
int aux;
for (int j = 0; j < 100; j++)
{
var watch = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
aux = a.Prop;
a.Prop = aux;
}
watch.Stop();
propertyExecutionTimes.Add(watch.ElapsedMilliseconds);
watch = System.Diagnostics.Stopwatch.StartNew();
for (int i = 0; i < 10000000; i++)
{
aux = a.Field;
a.Field = aux;
}
watch.Stop();
fieldExecutionTimes.Add(watch.ElapsedMilliseconds);
}
Console.WriteLine("Property best time: " + propertyExecutionTimes.OrderBy(x => x).First());
Console.WriteLine("Field best time: " + fieldExecutionTimes.OrderBy(x => x).First());
Console.ReadKey();
}
}
It consists of calling 10M times a field, vs calling 10M times a property everthing 10 times, and then it is picked the lowest value from each test. The results with a VS2012 release version were:
Property best time: 96
Field best time: 45
So as expected the results for a field were quite better than a property.
But after this I runned the program without debugger (simply run the .exe file) and as a surprise for me, the times were similar for both using field and a property like this:
Property best time: 20
Field best time: 20
In this case the differences between using a property and a field were none, which makes me consider that they are compiled in this case as the same, or the methods of the property were converted to something similar with inline
methods in C++. This made me think I should see how actual getters and setters are working copared to the property, so I have added a pair of getters and setters:
private int _field;
public int Get() { return _field; }
public void Set(int value) { _field = value; }
Similar testing this against a property with a few changes to respect the same behavior:
aux = a.Get();
a.Set(aux);
Gave me this output:
Property best time: 96
Methods best time: 96
With debugger and:
Property best time: 20
Methods best time: 20
Without debugger. These values are the same, so I concluded that auto-properties are getters and setters which are compiled just like fields. Is this a correct conclusion? And finaly, why the field was also faster than a property when the debugger was attached?
答案 0 :(得分:1)
These values are the same, so I concluded that auto-properties are getters and setters which are compiled just like fields.
Yes, auto-properties are implemented as a field, and a get and optionally a set accessor for that field.
Is this a correct conclusion?
For the wrong reasons, but yes. :) To accurately see how auto-properties are implemented, don't rely on timing, but create a program or library and open that in a MSIL disassembler. As you've seen, timing results can be misleading.
And finaly, why the field was also faster than a property when the debugger was attached?
When debugging, there are far fewer opportunities for things like inlining, since inlining makes it more difficult to set a break point, to support edit-and-continue, etc. It's mainly inlining that makes property accessors as fast as direct field access.