Was ist der Unterschied zwischen ldsfld und ldstr in IL?

7

Ich habe einen Artikel über String.Empty vs "" gelesen und teste mich auch selbst. Unterschiedlich zwischen ihnen sind unten.

String.Empty

%Vor%

""

%Vor%

Nachdem ich mit meinen Freunden gesprochen habe, argumentieren sie, dass String.Empty schneller ist als "", da unter der Haube (auf Assembly-Ebene) ldstr mehr 1 Kreis als ldsfld macht. (Ich kann mich nicht erinnern, Schritte, die sie anders machen)

Ich möchte wissen, wie ich diesen Aspekt der Leistung überprüfen kann.

    
Anonymous 09.09.2010, 06:31
quelle

3 Antworten

12

Die Operation ldsfld drückt den Wert eines statischen Feldes auf den Auswertungsstapel, während ldstr einen Verweis auf ein Meta-String-Literal verschiebt.

Der Leistungsunterschied (falls vorhanden) wäre minimal. Neuere Versionen des Compilers ersetzen "" für String.Empty .

Sie sollten auch die Lesbarkeit und Wartbarkeit des Codes berücksichtigen. Mit String.Empty ist es klarer, dass Sie eigentlich eine leere Zeichenfolge meinen und nicht nur vergessen haben, etwas in das String-Literal einzugeben.

Bearbeiten:

Ich habe mir den erstellten nativen Code angesehen.

C # 3, Freigabemodus, x86:

%Vor%

C # 3, Freigabemodus, x64:

%Vor%

Am Ende ist der Code also identisch.

    
Guffa 09.09.2010, 06:41
quelle
7

Ab .NET 4.5 ist der Unterschied in diesem Fall : genau nichts. Es sieht so aus, als ob das JIT diese ldsfld erkennt und die interne leere Zeichenkette direkt injiziert.

Sie können das sagen, weil in & lt; 4.5, können Sie den Wert von string.Empty über Reflektion ändern und es wirkt sich auf den Code mit string.Empty aus. Böse aber möglich. Ab 4.5 funktioniert das nicht mehr. Wenn Sie über Reflektion überprüfen können, erhalten Sie die gehackte Version, aber Code mit string.Empty via ldsfld erhält die richtige leere Zeichenfolge statt der gehackten Version.

    
Marc Gravell 31.03.2013 22:12
quelle
4

ldstr ist IL, um ein bestimmtes Zeichenfolgen-Token aus Metadaten zu laden.

ldsfld ist IL zum Laden des angegebenen Feldes - was in diesem Fall string.Empty ist.

Mit anderen Worten, sie sind völlig verschiedene Operationen, die in diesem Fall das gleiche Ergebnis haben. Wie werden sie auf der Assembly-Ebene implementiert? Nun, das könnte sehr gut von der Version der CLR abhängen, die Sie verwenden. Fragen Sie Ihre Freunde, über welche Version sie sprechen ... Desktop (32 oder 64 Bit? 1, 2, 2SP1, 2SP2, 4?), Compact Framework (wieder welche Version?), Silverlight (welches Betriebssystem, welche Version? ?) Haben sie cordbg für den Code verwendet, den Sie gerade diskutieren, oder haben sie das für einen Beispielcode getan, der möglicherweise nicht auf die gleiche Weise optimiert wurde?

Ich hätte (und hätte) argumentiert, dass Sie das verwenden sollten, was Sie besser finden. Persönlich bevorzuge ich "" aber andere bevorzugen string.Empty . Das ist gut. Aus Performancegründen gegeneinander zu argumentieren, erfordert Beweise obwohl ... und im Idealfall Beweise basierend auf dem Code, den Sie tatsächlich schreiben, kein Mikro-Benchmark.

Ich wäre erstaunt , um einen Code zu sehen, bei dem ein Unterschied zwischen den beiden tatsächlich zu einem signifikanten Leistungsunterschied im realen Code führte - anders als in Situationen, in denen es wahrscheinlich einen besseren Weg gibt, sich der Aufgabe zu nähern.

    
Jon Skeet 09.09.2010 06:36
quelle

Tags und Links