Bitte beachten Sie, dass diese Frage nur die Leistung betrifft. Überspringen wir Designrichtlinien, Philosophie, Kompatibilität, Portabilität und alles, was nicht mit reiner Leistung zu tun hat. Vielen Dank.
Nun zur Frage. Ich habe immer angenommen, dass das Lesen von öffentlichen Feldern schneller sein muss als das Aufrufen eines Getters, da C # -Getter / Setter wirklich verdeckte Methoden sind.
Also, um sicherzugehen, dass ich einen Test gemacht habe (der Code unten). Dieser Test führt jedoch nur dann zu erwarteten Ergebnissen (dh Felder sind mit 34% schneller als Getter ), wenn Sie ihn in Visual Studio ausführen.
Sobald Sie es über die Befehlszeile ausführen, wird fast das gleiche Timing angezeigt ...
Die einzige Erklärung könnte sein, dass die CLR zusätzliche Optimierungen vornimmt (korrigieren Sie mich, wenn ich hier falsch liege).
Ich glaube nicht, dass in einer realen Anwendung, in der diese Eigenschaften auf viel komplexere Weise verwendet werden, sie auf die gleiche Weise optimiert werden.
Bitte helfen Sie mir, die Idee zu beweisen oder zu widerlegen, dass Immobilien im wirklichen Leben langsamer sind als Felder.
Die Frage ist: Wie soll ich die Testklassen ändern, damit sich die CLR ändert, damit das öffentliche Feld die Getter übertrifft? ODER zeigen Sie mir, dass jede Eigenschaft ohne interne Logik dieselbe Leistung wie ein Feld erbringt (zumindest auf dem Getter).
EDIT: Ich spreche nur über Release 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;
}
}