Betrachten Sie diesen Code:
%Vor% Soweit ich sehen kann, sollten die Methoden FillUsingAsNullable
und FillUsingOwnCode
gleichwertig sein.
Aber es sieht so aus, als wäre die Version "eigener Code" deutlich schneller.
Es gibt Optionen 2
zum Kompilieren von "x86" oder "x64" und 2
Auswahlmöglichkeiten zum Kompilieren von "Debug" oder "Release (Optimierungen)" und 3
Auswahlmöglichkeiten für was in GetObject
zurückgegeben werden soll Methode. Soweit ich sehen kann, ist die Version "eigener Code" in all diesen Fällen 2*2*3 == 12
deutlich schneller als die Version "as nullable".
Die Frage: Ist as
mit Nullable<>
unnötig langsam, oder fehlt mir hier (ziemlich wahrscheinlich) etwas?
Zugehöriger Thread: Performanceüberraschung mit "as" - und nullable-Typen .
Die generierte IL ist anders, aber nicht grundlegend. Wenn der JIT gut war, was nicht der Fall ist, und das keine Neuigkeiten sind, könnte dies auf genau den gleichen x86-Code kompiliert werden.
Ich habe dies mit VS2010 Release AnyCPU zusammengestellt.
as
version:
?:
version:
Die Beschreibungen der Opcodes sind auf MSDN. Das Verständnis dieser IL ist nicht schwierig und jeder kann es tun. Es ist ein wenig zeitaufwendig für das unerfahrene Auge, obwohl.
Der Hauptunterschied besteht darin, dass die Version mit der Verzweigung im Quelltext auch eine Verzweigung in der generierten AWL hat. Es ist nur ein bisschen weniger elegant. Der C # -Compiler hätte dies eventuell optimieren können, aber die Strategie des Teams besteht darin, sich über Optimierungen Sorgen machen zu müssen. Würde gut funktionieren, wenn die JIT dann notwendige Investitionen bekommen würde.
Sie können dies weiter analysieren, indem Sie sich das vom JIT emittierte x86 ansehen. Sie werden einen offensichtlichen Unterschied finden, aber es wird eine unspektakuläre Entdeckung sein. Ich werde nicht die Zeit dafür investieren.
Ich habe die as
Version modifiziert, um auch einen temporären zu verwenden, um einen fairen Vergleich zu haben:
Ich denke, dass Ihre Testergebnisse von Messfehlern dominiert werden.
Hier ist mein Programm:
%Vor% Hier ist, was ich in Release, außerhalb Debugger, mit return 42
:
Beachten Sie, dass zwischen den Läufen eine ziemlich große Varianz besteht. Sie müssten wahrscheinlich mehrere Male hintereinander laufen, um eine gute Metrik für die Leistung zu erhalten.
Folgendes geschieht, wenn wir GetObject()
ändern, um (int?)42
zurückzugeben.
Und nochmal, mit der gleichen Konfiguration:
%Vor%Wenn Sie wirklich aussagekräftige Daten sammeln möchten, schlage ich vor, die beiden Tests in verschiedenen Reihenfolgen mehrmals zu wiederholen und dabei den Mittelwert und die Standardabweichung zu betrachten.
Ich vermute, dass die größte Zeitsenke bei diesen Methoden die Ungültigkeit des Speichercache ist, so dass das Ergebnis für einen gegebenen Test wahrscheinlich davon abhängt, wo genau das Array für jeden Test zugewiesen wird und wann GC während der häufigen Boxzuweisungen eintritt .
Tags und Links c# performance nullable as-operator