Обратите внимание, что этот вопрос связан только с производительностью. Позволяет пропустить принципы проектирования, философию, совместимость, мобильность и все, что не связано с чистой производительностью. Спасибо.
Теперь на вопрос. Я всегда предполагал, что, поскольку С# getters/setters действительно маскируют методы, тогда чтение публичного поля должно быть быстрее, чем вызов getter.
Итак, чтобы убедиться, что я сделал тест (код ниже). Однако этот тест дает только ожидаемые результаты (т.е. Поля быстрее, чем получатели на 34%) , если вы запускаете его изнутри Visual Studio.
Как только вы запустите его из командной строки, он отображает практически то же время...
Единственное объяснение может заключаться в том, что CLR делает дополнительную оптимизацию (исправьте меня, если я ошибаюсь здесь).
Я не верю, что в реальном приложении, где эти свойства используются гораздо более сложным способом, они будут оптимизированы одинаково.
Пожалуйста, помогите мне доказать или опровергнуть мысль о том, что в реальной жизни свойства медленнее полей.
Вопрос в том, как изменить тестовые классы, чтобы изменить поведение CLR, чтобы публичное поле превосходило получателей. ИЛИ покажите мне, что любое свойство без внутренней логики будет работать так же, как поле (по крайней мере, на получателе)
EDIT: я говорю только о выпуске x64 build.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace PropertyVsField
{
class Program
{
static int LEN = 20000000;
static void Main(string[] args)
{
List<A> a = new List<A>(LEN);
List<B> b = new List<B>(LEN);
Random r = new Random(DateTime.Now.Millisecond);
for (int i = 0; i < LEN; i++)
{
double p = r.NextDouble();
a.Add(new A() { P = p });
b.Add(new B() { P = p });
}
Stopwatch sw = new Stopwatch();
double d = 0.0;
sw.Restart();
for (int i = 0; i < LEN; i++)
{
d += a[i].P;
}
sw.Stop();
Console.WriteLine("auto getter. {0}. {1}.", sw.ElapsedTicks, d);
sw.Restart();
for (int i = 0; i < LEN; i++)
{
d += b[i].P;
}
sw.Stop();
Console.WriteLine(" field. {0}. {1}.", sw.ElapsedTicks, d);
Console.ReadLine();
}
}
class A
{
public double P { get; set; }
}
class B
{
public double P;
}
}