61 Stimmen

Optimiert C# die Verkettung von String-Literalen?

Weiß der Compiler zum Beispiel, dass er Folgendes übersetzen muss

string s = "test " + "this " + "function";

zu

string s = "test this function";

und so die Leistungseinbußen durch die String-Verkettung vermeiden?

69voto

Jon Skeet Punkte 1325502

Ja, das ist in der C#-Spezifikation garantiert. Es steht in Abschnitt 7.18 (der C# 3.0 Spezifikation):

Wann immer ein Ausdruck die Bedingung Anforderungen erfüllt, wird der Ausdruck zur Kompilierzeit ausgewertet. Dies gilt auch dann, wenn der Ausdruck ein Unterausdruck eines größeren Ausdrucks ist, der nicht-konstante Konstrukte enthält.

(Die "oben genannten Anforderungen" schließen den Operator + ein, der auf zwei konstante Ausdrücke angewendet wird).

Siehe auch diese Frage .

27voto

Michael Burr Punkte 320591

Nur eine Randbemerkung zu einem verwandten Thema - der C#-Compiler 'optimiert' auch mehrfache Verkettungen mit nicht-literalen Werten, indem er die ' + ' zu einem einzigen Aufruf einer Überladung der Methode String.Concat() mit mehreren Parametern.

Also

string result = x + y + z;

kompiliert zu etwas Gleichwertigem wie

string result = String.Concat( x, y, z);

und nicht die naivere Möglichkeit:

string result = String.Concat( String.Concat( x, y), z);

Nichts Weltbewegendes, aber ich wollte der Diskussion über die Optimierung der Verkettung von Zeichenkettenliteralen nur diesen Punkt hinzufügen. Ich weiß nicht, ob dieses Verhalten durch den Sprachstandard vorgeschrieben ist oder nicht.

11voto

FlySwat Punkte 165766

Ja.

C# optimiert nicht nur die Verkettung von Stringliteralen, sondern fasst auch äquivalente Stringliterale zu Konstanten zusammen und verwendet Zeiger, um alle Verweise auf dieselbe Konstante zu referenzieren.

8voto

Jed Punkte 10149

Ja - Sie können dies explizit mit ILDASM sehen.

Ejemplo:

Hier ist ein Programm, das Ihrem Beispiel ähnlich ist, gefolgt von dem kompilierten CIL-Code:

Hinweis: Ich verwende die Funktion String.Concat() nur, um zu sehen, wie der Compiler die beiden unterschiedlichen Methoden der Verkettung behandelt.

Programm

class Program
{
    static void Main(string[] args)
    {
        string s = "test " + "this " + "function";
        string ss = String.Concat("test", "this", "function");
    }
}

ILDASM

.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       29 (0x1d)
  .maxstack  3
  .locals init (string V_0,
           string V_1)
  IL_0000:  nop
  IL_0001:  ldstr      "test this function"
  IL_0006:  stloc.0
  IL_0007:  ldstr      "test"
  IL_000c:  ldstr      "this"
  IL_0011:  ldstr      "function"
  IL_0016:  call       string [mscorlib]System.String::Concat(string,
                                                              string,
                                                              string)
  IL_001b:  stloc.1
  IL_001c:  ret
} // end of method Program::Main

Beachten Sie, wie der Compiler bei IL_0001 die Konstante "test this function" erstellt hat, im Gegensatz zu der Art und Weise, wie der Compiler die Funktion String.Concat() behandelt - die für jeden der .Concat()-Parameter eine Konstante erstellt und dann die Funktion .Concat() aufruft.

6voto

Kev Punkte 115293

Aus berufenem Munde:

Unter Verkettung versteht man das Anhängen einer Zeichenkette an das Ende einer anderen Zeichenkette. Wenn Sie Zeichenkettenliterale oder Zeichenkettenkonstanten mit dem Operator + konkatenieren, erstellt der Compiler eine einzige Zeichenkette. Während der Laufzeit findet keine Verkettung statt. String-Variablen können jedoch nur zur Laufzeit konkateniert werden. In diesem Fall sollten Sie sich über die Auswirkungen der verschiedenen Ansätze auf die Leistung im Klaren sein.

http://msdn.microsoft.com/en-us/library/ms228504.aspx

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