24 Stimmen

Warum ist String.IsNullOrEmpty schneller als String.Length?

ILSpy zeigt, dass String.IsNullOrEmpty in Bezug auf String.Length implementiert ist. Aber warum ist dann String.IsNullOrEmpty(s) schneller als s.Length == 0?

Zum Beispiel ist es in diesem Benchmark 5% schneller:

var stopwatches = Enumerable.Range(0, 4).Select(_ => new Stopwatch()).ToArray();
var strings = "A,B,,C,DE,F,,G,H,,,,I,J,,K,L,MN,OP,Q,R,STU,V,W,X,Y,Z,".Split(',');
var testers = new Func[] { s => s == String.Empty, s => s.Length == 0, s => String.IsNullOrEmpty(s), s => s == "" };
int count = 0;
for (int i = 0; i < 10000; ++i) {
    stopwatches[i % 4].Start();
    for (int j = 0; j < 1000; ++j)
        count += strings.Count(testers[i % 4]);
    stopwatches[i % 4].Stop();
}

(Andere Benchmarks zeigen ähnliche Ergebnisse. Dieser hier minimierte den Effekt von überflüssigen Prozessen auf meinem Computer. Außerdem kamen die Tests, die mit leeren Zeichenfolgen verglichen wurden, auf dasselbe Ergebnis, etwa 13% langsamer als IsNullOrEmpty.)

Zusätzlich, warum ist IsNullOrEmpty nur auf x86 schneller, während auf x64 String.Length etwa 9% schneller ist?

Update: Details zur Testeinrichtung: .NET 4.0 auf 64-Bit Windows 7, Intel Core i5 Prozessor, Konsolenprojekt, kompiliert mit aktivierter "Optimierung des Codes". Allerdings war auch "JIT-Optimierung beim Modulladen unterdrücken" aktiviert (siehe akzeptierte Antwort und Kommentare).

Bei vollständig aktivierter Optimierung ist Length etwa 14% schneller als IsNullOrEmpty mit dem Delegaten und anderem Overhead entfernt, wie in diesem Test:

var strings = "A,B,,C,DE,F,,G,H,,,,I,J,,K,L,MN,OP,Q,R,,STU,V,,W,,X,,,Y,,Z,".Split(',');
int count = 0;
for (uint i = 0; i < 100000000; ++i)
    count += strings[i % 32].Length == 0 ? 1 : 0; // Längentest durch String.IsNullOrEmpty ersetzen

-2voto

Marshal Punkte 6391

In CLR via CSharp Kapitel 10 "Properties" schreibt Jeff Richter:

Ein Eigenschaftsmethode kann lange dauern, um ausgeführt zu werden; der Feldzugriff wird immer sofort abgeschlossen. Ein häufiger Grund für die Verwendung von Eigenschaften besteht darin, die Thread-Synchronisierung durchzuführen, was den Thread für immer stoppen kann, und daher sollte eine Eigenschaft nicht verwendet werden, wenn eine Thread-Synchronisierung erforderlich ist. In dieser Situation wird eine Methode bevorzugt. Außerdem, wenn auf Ihre Klasse aus der Ferne zugegriffen werden kann (zum Beispiel, wenn Ihre Klasse von System.MarshalByRefObject abgeleitet ist), wird der Aufruf der Eigenschaftsmethode sehr langsam sein, daher bevorzugt man eine Methode gegenüber einer Eigenschaft. Nach meiner Meinung sollten Klassen, die von MarshalByRefObject abgeleitet sind, niemals Eigenschaften verwenden.

Also, wenn wir sehen, dass String.Length eine Eigenschaft ist und String.IsNullOrEmpty eine Methode ist, die schneller ausgeführt werden kann als die Eigenschaft String.Length.

-4voto

McRasta Punkte 1

Es könnte durch die Arten der beteiligten Variablen verursacht werden. *Leer scheint einen boolean zu verwenden, Länge ein int (denke ich).

Friede!

  • : bearbeiten

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X