auto 属性 是如何编译的?
How an auto property is compiled?
我是在看到一些关于属性和自动属性以及编译器如何表示它们的问题和答案后才问这个问题的。
据我了解,auto-属性 表示为一个字段,有两种方法,getter 和 setter。在这种情况下,如果使用字段,访问该字段的代码应该比访问 属性 的代码更快,因为它避免了对方法的任何补充调用。为了证明这个理论,我写了下面的代码,请原谅我的代码:
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();
}
}
它包括对一个字段调用 10M 次,与对一个 属性 调用 10M 次 everthing 10 次,然后从每次测试中选择最低值。 VS2012 发布版本的结果是:
Property best time: 96
Field best time: 45
正如预期的那样,字段的结果比 属性 好得多。
但是 之后我 运行 在没有调试器的情况下编译了程序(只是 运行 .exe 文件),令我惊讶的是,时间像这样使用字段和 属性 是相似的:
Property best time: 20
Field best time: 20
在这种情况下,使用 属性 和字段之间的区别是 none,这让我认为它们在这种情况下被编译为相同的,或者 属性 被转换为与 C++ 中的 inline
方法类似的东西。这让我觉得我应该看看实际的 getters 和 setters 与 属性 相比如何工作,所以我添加了一对 getters 和 [=43] =]s:
private int _field;
public int Get() { return _field; }
public void Set(int value) { _field = value; }
针对 属性 进行类似的测试,并进行一些更改以尊重相同的行为:
aux = a.Get();
a.Set(aux);
给我这个输出:
Property best time: 96
Methods best time: 96
使用调试器和:
Property best time: 20
Methods best time: 20
没有调试器。这些值是相同的,所以我得出结论,自动属性是 getters 和 setters,它们像字段一样编译。这是一个正确的结论吗?最后,为什么附加调试器时该字段也比 属性 快?
These values are the same, so I concluded that auto-properties are getters and setters which are compiled just like fields.
是的,自动属性实现为一个字段,以及该字段的 get 和可选的 set 访问器。
Is this a correct conclusion?
出于错误的原因,但是是的。 :) 要准确查看自动属性是如何实现的,不要依赖时间,而是创建一个程序或库并在 MSIL 反汇编程序中打开它。如您所见,计时结果可能会产生误导。
And finaly, why the field was also faster than a property when the debugger was attached?
调试时,内联之类的机会要少得多,因为内联使得设置断点、支持编辑并继续等变得更加困难。主要是内联使得 属性访问器与直接字段访问一样快。
我是在看到一些关于属性和自动属性以及编译器如何表示它们的问题和答案后才问这个问题的。
据我了解,auto-属性 表示为一个字段,有两种方法,getter 和 setter。在这种情况下,如果使用字段,访问该字段的代码应该比访问 属性 的代码更快,因为它避免了对方法的任何补充调用。为了证明这个理论,我写了下面的代码,请原谅我的代码:
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();
}
}
它包括对一个字段调用 10M 次,与对一个 属性 调用 10M 次 everthing 10 次,然后从每次测试中选择最低值。 VS2012 发布版本的结果是:
Property best time: 96
Field best time: 45
正如预期的那样,字段的结果比 属性 好得多。
但是 之后我 运行 在没有调试器的情况下编译了程序(只是 运行 .exe 文件),令我惊讶的是,时间像这样使用字段和 属性 是相似的:
Property best time: 20
Field best time: 20
在这种情况下,使用 属性 和字段之间的区别是 none,这让我认为它们在这种情况下被编译为相同的,或者 属性 被转换为与 C++ 中的 inline
方法类似的东西。这让我觉得我应该看看实际的 getters 和 setters 与 属性 相比如何工作,所以我添加了一对 getters 和 [=43] =]s:
private int _field;
public int Get() { return _field; }
public void Set(int value) { _field = value; }
针对 属性 进行类似的测试,并进行一些更改以尊重相同的行为:
aux = a.Get();
a.Set(aux);
给我这个输出:
Property best time: 96
Methods best time: 96
使用调试器和:
Property best time: 20
Methods best time: 20
没有调试器。这些值是相同的,所以我得出结论,自动属性是 getters 和 setters,它们像字段一样编译。这是一个正确的结论吗?最后,为什么附加调试器时该字段也比 属性 快?
These values are the same, so I concluded that auto-properties are getters and setters which are compiled just like fields.
是的,自动属性实现为一个字段,以及该字段的 get 和可选的 set 访问器。
Is this a correct conclusion?
出于错误的原因,但是是的。 :) 要准确查看自动属性是如何实现的,不要依赖时间,而是创建一个程序或库并在 MSIL 反汇编程序中打开它。如您所见,计时结果可能会产生误导。
And finaly, why the field was also faster than a property when the debugger was attached?
调试时,内联之类的机会要少得多,因为内联使得设置断点、支持编辑并继续等变得更加困难。主要是内联使得 属性访问器与直接字段访问一样快。