【发布时间】:2016-07-11 19:02:46
【问题描述】:
在我看到一些关于属性和自动属性以及编译器如何表示它们的问题和答案后,我问这个问题。
据我了解,自动属性表示为一个字段,有两种方法,一个 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 次一个属性 10 次,然后从每个测试中选择最低值。 VS2012 发布版本的结果是:
Property best time: 96
Field best time: 45
因此,正如预期的那样,字段的结果比属性要好得多。
但是在此之后我在没有调试器的情况下运行了程序(只需运行 .exe 文件),令我惊讶的是,使用字段和这样的属性的时间相似:
Property best time: 20
Field best time: 20
在这种情况下,使用属性和字段之间的区别是没有的,这让我认为它们在这种情况下被编译为相同,或者属性的方法被转换为与inline 方法类似的东西C++。这让我觉得我应该看看实际的 getter 和 setter 是如何与属性相比的,所以我添加了一对 getter 和 setter:
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
没有调试器。这些值是相同的,所以我得出结论,自动属性是 getter 和 setter,它们的编译就像字段一样。这是一个正确的结论吗?最后,为什么在附加调试器时字段也比属性快?
【问题讨论】:
-
使用 C# 时实际上有两个编译步骤(假设您没有使用 .NET Native 之类的东西)。在“编译时”输出 MSIL 的 C# 编译器和在运行时生成机器代码的 JIT 编译器。 JIT 执行您推测的内联优化。当附加调试器以改善调试体验时,它还会生成不同的、次优的机器代码。
-
谢谢@mikez,这并不能完全回答我的问题,但它是一个有价值的信息
标签: c# visual-studio-2012 properties compilation