2016-07-11 14 views
0

Ich frage dies, nachdem ich einige Fragen und Antworten zu Eigenschaften und Autoeigenschaften und wie diese vom Compiler dargestellt werden.Wie wird eine automatische Eigenschaft kompiliert?

Von was ich verstanden habe, wird eine Auto-Eigenschaft als ein Feld dargestellt, mit zwei Methoden, einem Getter und einem Setter. Wenn in diesem Fall ein Feld verwendet wird, sollte der Code für den Zugriff auf dieses Feld schneller sein als der Code, der auf eine Eigenschaft zugreift, da dadurch ein zusätzlicher Aufruf von Methoden vermieden wird. Um diese Theorie zu beweisen, dass ich schrieb den folgenden Code ein, und bitte, entschuldigen Sie, wie es aussieht:

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(); 
    } 
} 

Es 10M Zeiten des Aufrufs ein Feld vs Aufruf 10M mal eine Eigenschaft Everthing 10mal besteht, und Dann wird aus jedem Test der niedrigste Wert ausgewählt. Die Ergebnisse mit einer VS2012-Release-Version waren:

Property best time: 96 
Field best time: 45 

So erwartet, da die Ergebnisse für ein Feld waren recht besser als eine Eigenschaft.

Aber danach runned ich das Programm ohne Debugger (einfach die EXE-Datei ausgeführt wird) und als Überraschung für mich, die Zeiten für beide mit dem Feld ähnlich waren und eine Eigenschaft wie folgt:

Property best time: 20 
Field best time: 20 

In diesem Fall waren die Unterschiede zwischen der Verwendung einer Eigenschaft und eines Felds keine, was mich dazu bringt, dass sie in diesem Fall als dieselben kompiliert werden, oder die Methoden der Eigenschaft wurden in ähnliche Methoden mit inline Methoden in C++ konvertiert. Das machte ich denke, ich soll sehen, wie tatsächliche Getter und Setter sind auf das Grundstück copared Arbeiten, so habe ich ein Paar von Getter und Setter hinzugefügt:

private int _field; 
public int Get() { return _field; } 
public void Set(int value) { _field = value; } 

ähnlicher Tests dieses gegen eine Eigenschaft mit einigen Änderungen des respektieren gleiches Verhalten:

aux = a.Get(); 
a.Set(aux); 

Gab mir diese Ausgabe:

Property best time: 96 
Methods best time: 96 

mit Debugger und:

Property best time: 20 
Methods best time: 20 

Ohne Debugger. Diese Werte sind die gleichen, daher kam ich zu dem Schluss, dass auto-properties Getter und Setter sind, die genau wie Felder kompiliert werden. Ist das eine korrekte Schlussfolgerung? Und schließlich, warum war das Feld auch schneller als eine Eigenschaft, als der Debugger angeschlossen wurde?

+1

Es gibt effektiv zwei Kompilierungsschritte bei der Verwendung von C# (vorausgesetzt, Sie verwenden nicht so etwas wie .NET Native). Der C# -Compiler, der MSIL zur "Kompilierzeit" ausgibt und der JIT-Compiler, der zur Laufzeit Maschinencode erzeugt. Das JIT führt die Inlining-Optimierung durch, über die Sie spekuliert haben. Wenn der Debugger angefügt wird, erzeugt es auch anderen suboptimalen Maschinencode, um das Debuggerlebnis zu verbessern. –

+0

Danke @mikez, das beantwortet meine Frage nicht vollständig, aber es ist eine wertvolle Information – meJustAndrew

Antwort

1

Diese Werte sind die gleichen, daher kam ich zu dem Schluss, dass auto-properties Getter und Setter sind, die genau wie Felder kompiliert werden.

Ja, Auto-Eigenschaften sind als Feld implementiert, und ein Get und optional ein Set-Accessor für dieses Feld.

Ist dies eine korrekte Schlussfolgerung?

Aus den falschen Gründen, aber ja. :) Um genau zu sehen, wie Auto-Eigenschaften implementiert werden, verlassen Sie sich nicht auf Timing, sondern erstellen Sie ein Programm oder eine Bibliothek und öffnen Sie das in einem MSIL-Disassembler. Wie Sie gesehen haben, können Timing-Ergebnisse irreführend sein.

Und schließlich, warum das Feld war auch schneller als eine Eigenschaft, als der Debugger angeschlossen war?

Beim Debuggen, da weit weniger Möglichkeiten für Dinge wie inlining sind, da inlining macht es schwieriger, einen Haltepunkt zu setzen, zu unterstützen, zu bearbeiten und fortsetzt, usw. vor allem Es inlining das macht Eigenschaftenaccessoren so schnell als direkter Feldzugriff.

+0

Ich muss zugeben, dass ich bis jetzt keine binäre Datei zerlegt habe, also brauchte ich etwas Zeit. Zuerst habe ich einen DLL-Build im Release-Modus disassembliert, also zeigte er mir nicht viele Dinge, aber als ich die Debug-Version ausprobierte, war ich überrascht! Ich konnte sehen, wie die gesamte Struktur gehalten wurde. Danke für die Antwort, es ließ mich noch etwas arbeiten, aber es hat sich gelohnt. Haben Sie einen guten Tag! – meJustAndrew