11 Stimmen

Wie hoch sind die Leistungskosten für die Zuweisung eines einzelnen Zeichenkettenwerts unter Verwendung von Pluszeichen?

Ich habe mich oft gefragt, gibt es eine Leistung Kosten der Aufteilung einer Zeichenfolge über mehrere Zeilen, um die Lesbarkeit zu erhöhen, wenn zunächst einen Wert zu einer Zeichenfolge zuweisen. Ich weiß, dass Zeichenketten unveränderlich sind und daher jedes Mal eine neue Zeichenkette erstellt werden muss. Außerdem sind die Leistungskosten dank der heutigen sehr schnellen Hardware eigentlich irrelevant (es sei denn, man befindet sich in einer teuflischen Schleife). Also zum Beispiel:

String newString = "This is a really long long long long long" +
    " long long long long long long long long long long long long " +
    " long long long long long long long long long string for example.";

Wie gehen die JVM oder der Compiler von .Net und andere Optimierungen damit um? Wird eine einzige Zeichenkette erstellt? Oder wird eine Zeichenkette erstellt, dann eine neue, in der der Wert verkettet wird, und dann eine weitere, in der die Werte erneut verkettet werden?

Das ist nur für meine eigene Neugierde.

28voto

Jon Skeet Punkte 1325502

Die C#-Spezifikation garantiert, dass dies identisch mit der Erstellung der Zeichenkette in einem einzelnen Literal ist, da es sich um eine Kompilierzeitkonstante handelt. Aus Abschnitt 7.18 der C# 3 Spezifikation:

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

(In der Spezifikation finden Sie die genauen Angaben zu den "oben genannten Anforderungen" :)

In der Java-Sprachenspezifikation ist dies am Ende von Abschnitt 3.10.5 :

Mit der Konstante berechnete Zeichenketten Ausdrücke (§15.28) berechnet werden, werden zur Kompilierzeit berechnet und dann so behandelt, als ob sie Literale wären.

14voto

coobird Punkte 155882

In Java verwandelt der Compiler die String in eine Konstante.

class LongLongString
{
    public LongLongString()
    {
        String newString = "This is a really long long long long long" +
            " long long long long long long long long long long long long " +
            " long long long long long long long long long string for example.";
    }

    public static void main(String[] args)
    {
        new LongLongString();
    }
}

Wird kompiliert in:

Compiled from "LongLongString.java"
class LongLongString extends java.lang.Object{
public LongLongString();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   ldc #2; //String This is a really long long long long long long long long long long long long long long long long long  long long long long long long long long long string for example.
   6:   astore_1
   7:   return

public static void main(java.lang.String[]);
  Code:
   0:   new #3; //class LongLongString
   3:   dup
   4:   invokespecial   #4; //Method "<init>":()V
   7:   pop
   8:   return

}

Wie zu sehen ist, wird in Zeile 4 eine einzige Zeile geladen und nicht mehrere String Instanzen geladen werden.

Editar: Die Quelldatei wurde kompiliert mit javac Version 1.6.0_06. Anschauen Die Java Sprachspezifikation, Dritte Ausgabe (und derselbe Abschnitt, der in Antwort von Jon Skeet ), konnte ich keinen Hinweis darauf finden, ob ein Compiler eine mehrzeilige String in eine einzige String daher ist dieses Verhalten wahrscheinlich compiler-implementierungsspezifisch.

6voto

Drew Noakes Punkte 282438

Testen Sie dies selbst. In C#-Code (gleichwertiges Java würde auch funktionieren):

string x = "A" + "B" + "C";
string y = "ABC";

bool same = object.ReferenceEquals(x, y); // true

Sie werden sehen, dass das Ergebnis lautet true .

Nebenbei bemerkt werden Sie sehen, dass die Zeichenkette auch in den String-Pool der Laufzeit eingebunden ist:

bool interned = object.ReferenceEquals(x, string.Intern(x)); // true

5voto

david a. Punkte 5209

Kein Kompromiss bei der Leistung. Die Compiler-Optimierung wird das zu einem einzigen String zusammenfassen (zumindest in Java).

3voto

cjk Punkte 44394

Soweit ich mich erinnern kann, werden dabei nicht mehrere Zeichenketten erstellt, sondern nur eine einzige.

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