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?
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?
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 .
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.
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.
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.
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.