Ich habe jede in Testszenarien profiliert und ich sehe keinen sinnvollen Unterschied in der Geschwindigkeit, aber die Ausbeute brechen Version ist etwas schneller.
Ich gehe davon aus, dass Ihre Profiling-Tests Programmstartgeschwindigkeit nicht enthalten. Das Konstrukt yield
funktioniert, indem es eine Klasse für Sie generiert. Dieser zusätzliche Code ist ideal, wenn er die benötigte Logik bereitstellt. Wenn dies nicht der Fall ist, werden lediglich die Festplatten-E/A, die Größe des Arbeitssatzes und die JIT-Zeit hinzugefügt.
Wenn Sie ein Programm mit Ihrer Testmethode in ILSpy öffnen und enumerator Dekompilierungsprozeß deaktivieren, haben Sie eine Klasse mit dem Namen <GetLessThanNothing>d__0
mit einem Dutzend oder so Mitgliedern finden. Seine MoveNext
Methode sieht wie folgt aus:
bool IEnumerator.MoveNext()
{
int num = this.<>1__state;
if (num == 0)
{
this.<>1__state = -1;
}
return false;
}
EmptyEnumerable
Werke von lazily ein statisches leeres Array zu erstellen. Vielleicht ist der Grund, EmptyEnumerable
zu prüfen, ob das Array erstellt werden muss, langsamer als yield break
im isolierten Benchmarking, aber es würde wahrscheinlich eine ganze Reihe von Iterationen dauern, um den Startup-Penalty zu überwinden, und beide würden wahrscheinlich insgesamt nicht wahrnehmbar sein ein "Tod durch tausend Perf Papercuts" -Szenario.
Hier und überall sonst (außer ein Profiler sagt etwas anderes) –