Wie wichtig ist Verwendung von StringBuffer in Schleifen?

bur

Mitglied
Man liest öfters dass die Verwendung von += auf Stringobjekte in Schleifen zu schlechter Performance führt. Abhilfe soll das Verwenden von StringBuffer (oder Builder) schaffen.

Außerhalb von Schleifen wäre das nicht nötig, da der Compiler sowieso das += zu einem äquivalenten StringBuffer.append() umwandelt. Nur in Schleifen soll das nicht so gut funktionieren, weshalb man da eben direkt mit StringBuffer arbeiten soll.

Gilt das immer noch? Oder kann der Compiler mittlerweile auch mit dynamisch veränderten Strings gut umgehen?
 
M

maki

Gast
Gilt IMHO immer noch.

Ob das relevant ist lässt aber cniht sagen ohne zu messen, wenn diese Schleife zB. nur 10 mal durchlaufen wird, kann es egal sein ob StringBuilder(!!! StringBuffer ist langsamer) oder +
 

XHelp

Top Contributor
In den Schleifen wird += auch mit dem StringBuilder gemacht, nur da wird der StringBuilder jedes mal aufs neue initialisiert:
Java:
String s = "";
for (int i=0;i<20;i++) {
  s+="a";
}
Das könnte man auch manuell als
Java:
String s = "";
StringBuilder sb = new StringBuilder(s);
for (int i=0;i<20;i++) {
  sb.append("a");
}
s = sb.toString();

Aber der Compiler macht daraus:
Java:
String s = "";
for (int i=0;i<20;i++) {
  StringBuilder sb = new StringBuilder(s);
  sb.append("a");
  s = sb.toString();
}

Es kommt eben drauf an was in der Schleife passiert und wie oft sie durchgeführt wird. Meistens kann man ganz andere und sinnvollere Sachen optimieren, bevor man sich mit sowas beschäftigt
 

ARadauer

Top Contributor
definitiv, bei großen Strings. Also anängen von kurzen Texten an langen Log Texte usw.... das bremst...

Java:
public class Test {

    public static void main(String[] args) {

        int anzahl = 5000;

        long t = System.currentTimeMillis();

        String text =
                "Man liest öfters dass die Verwendung von += auf Stringobjekte in Schleifen zu schlechter Performance führt. Abhilfe soll das Verwenden von StringBuffer (oder Builder) schaffen."
                    + "Außerhalb von Schleifen wäre das nicht nötig, da der Compiler sowieso das += zu einem äquivalenten StringBuffer.append() umwandelt. Nur in Schleifen soll das nicht so gut funktionieren, weshalb man da eben direkt mit StringBuffer arbeiten soll."
                    + "+Gilt das immer noch? Oder kann der Compiler mittlerweile auch mit dynamisch veränderten Strings gut umgehen? ";

        String result = "";
        for (int i = 0; i < anzahl; i++) {
            if (i % 100 == 0)
                System.out.print(".");
            result += text;
        }
        System.out.println("t1: " + (System.currentTimeMillis() - t));
        t = System.currentTimeMillis();

        StringBuffer result2 = new StringBuffer();
        for (int i = 0; i < anzahl; i++) {
            if (i % 100 == 0)
                System.out.print(".");
            result2.append(text);
        }
        System.out.println("t2: " + (System.currentTimeMillis() - t));

    }

}
 

musiKk

Top Contributor
Aber der Compiler macht daraus:

Die Gründe dafür sind mir ein Rätsel. Compiler können doch schon lange sehr komplexe Optimierungen vornehmen; warum wird Java-Anfängern so ein Stolperstein in den Weg geworfen? Das sollte doch wirklich einfach optimierbar sein. Kennt jemand die Gründe dafür? Ändert sich da mit Java 7 etwas? (Ich bin aktuell noch auf Java 6; im OpenJDK 1.6.0_22 wird der [c]StringBuilder[/c] noch innerhalb der Schleife erzeugt.)
 

Empire Phoenix

Top Contributor
Strings sind imutable, das hat eine wichtige bedeutung bei der art wir referenzen geändert werden können und übergeben werden, wenn jetzt der kompiler nicht weiß wass der programmierer beabsichtigt, kann man damit vieles killen wenn man sowas nachträglich ändert.
 

bur

Mitglied
Strings sind imutable, das hat eine wichtige bedeutung bei der art wir referenzen geändert werden können und übergeben werden, wenn jetzt der kompiler nicht weiß wass der programmierer beabsichtigt, kann man damit vieles killen
Ok, das erklärt wieso die scheinbar naheliegende Optimierung mit einem neuen StringBuilder-Objekt und append() in der Schleife nicht einfach standardmäßig durchgeführt werden kann. Wenn mir jetzt auch kein Fall einfällt, bei dem es Probleme geben könnte.

Wieso sollte das für einen Anfänger ein Stolperstein bzw. überhaupt relevant sein?
Wenn ein harmlos wirkender Operator im Hintergrund einen umfangreichen Prozess auslöst, ist das nicht wirklich optimal. Stolperstein ist vielleicht übertrieben, aber ich könnte mir schon vorstellen dass das bei einigen zu eher langsamen Programmen geführt hat.

Was mir an der Stringbehandlung sowieso nicht gefällt:
Strings sind imutable
Nicht wirklich logisch finde ich zB folgendes:
Java:
public class Test {

    public static void main( String[] args ) {

    String s1 = new String( "String" );
    String s2 = "String";

    System.out.println( s1 == s2 );
    // FALSE
    
    String s3 = "String";
    
    System.out.println( s2 == s3 );
    // TRUE
    }
}
s1 und s2 verweisen nicht aufs gleiche Objekt. Das heißt für mich der Compiler macht aus [c]String s2 = "String";[/c] ein [c]String s2 = new String( "String" );[/c]. s2 und s3 sind dann aber wieder das gleiche Objekt. Für mich wenig intuitiv.

Ich habe das Gefühl man wollte die Stringbehandlung ähnlich gestalten wie in nicht-OOP und dabei kam dann diese Konstruktion heraus. Und das blockiert dann vielleicht die effektive Optimierung von += in Schleifen?
 

xehpuk

Top Contributor
s1 und s2 verweisen nicht aufs gleiche Objekt. Das heißt für mich der Compiler macht aus [c]String s2 = "String";[/c] ein [c]String s2 = new String( "String" );[/c]. s2 und s3 sind dann aber wieder das gleiche Objekt. Für mich wenig intuitiv.
Wie kommst du denn zu dem Entschluss? Ich denke, dass es genauso bleibt, wie es da steht. s1 ist eine Kopie von "String" aus dem Konstantenpool. Die Konstante "String" existiert ja schon, bevor du den Konstruktor aufrufst. s2 und s3 verweisen dann nur noch auf diese Konstante.
 

bur

Mitglied
Wie kommst du denn zu dem Entschluss?
Meinst du die Ausgabe von println? Das ist die echte Ausgabe aus dem Programm. s1 und s2 verweisen auf jeweils unterschiedliche Objekte.

Siehe: ideone.com Onlinecompiling

Bei s1 ist das noch verständlich, ich sage ja extra mit new dass ein neues Objekt angelegt werden soll. s2 referenziert dann aber nicht einfach das s1-Objekt, sondern es wird im Pool ein neues Objekt "String" angelegt. Bei s3 erkennt der Compiler dass "String" schon im Pool ist und referenziert das Objekt dann einfach, daher s2==s3.

Es gibt anscheinend zwei Bereiche für String-Objekte. Einmal solche die mit new angelegt wurden und dann die mit = "String" angelegten, die in den Pool wandern, bzw einen dort bereits existierenden String referenzieren. Anders kann ich mir nicht erklären dass s1 != s2. Und das ist es was ich umständlich und nicht passend zum sonstigen Objekt-System finde.
 
Zuletzt bearbeitet:

xehpuk

Top Contributor
Ich bezog mich schon aufs Zitat, also dass s2 plötzlich ein neuer String sein soll.

Für s2 wird kein neues "String" im Pool angelegt. Dort liegt bereits eins, nämlich das dem String-Konstruktor übergebenen.
Bei
Code:
String s1 = new String("String");
werden also zwei String-Instanzen erzeugt. Das als Parameter übergebene Literal wandert in den Pool, nur s1 dann eben nicht.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
ineedhelpinjava OOP Bitte wichtig Java Basics - Anfänger-Themen 6
Azazel Wie wichtig sind Castings in Java ? Java Basics - Anfänger-Themen 1
M Sind ternäre Operatoren für einen guten Programmierstil wichtig ? Java Basics - Anfänger-Themen 10
C Operationen auf Bitebene und Verschiebeoperatoren wichtig? Java Basics - Anfänger-Themen 26
X Nur ein Thread - Ist Threadsafe Berücksichtigung wichtig? Java Basics - Anfänger-Themen 22
L Wichtig! Benötige Hilfe bei Java! Java Basics - Anfänger-Themen 6
F Classpath: Wichtig für Runnable JAR? Java Basics - Anfänger-Themen 2
G welche Teile der api sind wichtig? Java Basics - Anfänger-Themen 3
U zweite Frage: return, wichtig Java Basics - Anfänger-Themen 8
I Schulprojekt !sehr wichtig! Java Basics - Anfänger-Themen 6
T Wie wichtig ist Design Patterns in einer Firma? Java Basics - Anfänger-Themen 8
P Turtle Wichtig! Wichtig! Morgen Abgabetermin! Java Basics - Anfänger-Themen 8
J Array - wichtig Java Basics - Anfänger-Themen 5
D Ergebnisse als .txt Speichern.wichtig. Java Basics - Anfänger-Themen 47
A Java Installtions Directory wichtig? Java Basics - Anfänger-Themen 12
T Verwendung jna Java Basics - Anfänger-Themen 15
L Zufälligen Zahlencode, ohne mehrfacher Verwendung einer Ziffer Java Basics - Anfänger-Themen 15
Kirby.exe Frage zur Verwendung von Interfaces Java Basics - Anfänger-Themen 6
S Exception bei Verwendung von LocalDate Java Basics - Anfänger-Themen 19
S Try-Catch in Verwendung einer while Schleife Java Basics - Anfänger-Themen 2
A OOP Richtige Verwendung von ArrayList und equals Java Basics - Anfänger-Themen 24
kilopack15 Verständnisfrage zur Verwendung von notify() bei Threads Java Basics - Anfänger-Themen 2
b1ck Scanner schließen, erneute Verwendung Java Basics - Anfänger-Themen 12
H Datentypen Fehler bei Verwendung von enum Java Basics - Anfänger-Themen 9
A Verwendung von Interfaces Java Basics - Anfänger-Themen 7
G Variablen Verwendung von Variablen in anderer Klasse Java Basics - Anfänger-Themen 6
G Verwendung von Konstruktor Java Basics - Anfänger-Themen 8
M Verwendung von System.exit(0) problematisch? Java Basics - Anfänger-Themen 1
D native Methoden, Verwendung? Java Basics - Anfänger-Themen 8
fLooojava kleines Projekt - Verwendung von Youtube Java Basics - Anfänger-Themen 22
X Array Ausgabe bei Verwendung von 2 Schleifen erklären Java Basics - Anfänger-Themen 8
G verwendung von regex Java Basics - Anfänger-Themen 3
K Problem bei der Verwendung von Gregorian Calender Java Basics - Anfänger-Themen 3
T NullPointerException bei Verwendung einer Klasse einer anderen .jar datei Java Basics - Anfänger-Themen 3
B Verwendung von Arrays Java Basics - Anfänger-Themen 2
U Verwendung von Interface Java Basics - Anfänger-Themen 33
A Methoden Verwendung von crypt? Java Basics - Anfänger-Themen 2
D Muss ich eigentlich immer auf die Verwendung des richtigen Datentyps achten? Java Basics - Anfänger-Themen 7
D reg Exp, verwendung des endezeichen "$" Java Basics - Anfänger-Themen 5
C Verwendung von Schleifen? Java Basics - Anfänger-Themen 18
J Datentypen Array - Verwendung im Konstruktor Java Basics - Anfänger-Themen 8
C Verwendung von primitiven Datentypen Java Basics - Anfänger-Themen 8
J Problem mit NullPointerException bei Verwendung eines Arrays Java Basics - Anfänger-Themen 6
D Frage zur Verwendung einer Schnittstelle Java Basics - Anfänger-Themen 4
A Verwendung von abstrakten Klassen Java Basics - Anfänger-Themen 17
D Verwendung der Klasse Map Java Basics - Anfänger-Themen 9
C Verwendung von Matrizen in einer Schleife Java Basics - Anfänger-Themen 5
F Umlaute eines Strings entfernen (Verwendung von this?) Java Basics - Anfänger-Themen 2
Daniel_L Verwendung von try und catch bei exceptions Java Basics - Anfänger-Themen 7
I Verwendung von Constant Field Values Java Basics - Anfänger-Themen 4
J Verwendung von eigenen Klassen in JSP Java Basics - Anfänger-Themen 2
G try. catch Verwendung Java Basics - Anfänger-Themen 11
Z Beispiel Würfelspiel mit Verwendung von Feldern Java Basics - Anfänger-Themen 7
H Verwendung lokaler Einstellungen Java Basics - Anfänger-Themen 4
G getName, substring Verwendung Java Basics - Anfänger-Themen 3
I Fehler bei Verwendung von substring Java Basics - Anfänger-Themen 4
S Verwendung von Super Java Basics - Anfänger-Themen 7
M Verwendung von Robot... wie? Java Basics - Anfänger-Themen 6
M Verwendung von "this" Java Basics - Anfänger-Themen 2
U Liste importieren und für weitere Verwendung sichern Java Basics - Anfänger-Themen 4
feuervogel Integral unter Verwendung der Java-Bibliothek berechnen Java Basics - Anfänger-Themen 10
frau-u Probleme mit richtiger Verwendung von FileInputStream Java Basics - Anfänger-Themen 2
S valueOf() vs. toString() Verwendung??? Java Basics - Anfänger-Themen 13
A Kurze Frage zur Verwendung von this Java Basics - Anfänger-Themen 9
S Verwendung bitweiser Operatoren Java Basics - Anfänger-Themen 6
F Verwendung von this in statischen Kontext nicht möglich Java Basics - Anfänger-Themen 8
B Compiler -> unendliche Schleife (StringBuffer?) Warum? Java Basics - Anfänger-Themen 2
C Stringbuffer auf Zeilenumbruch überprüfen Java Basics - Anfänger-Themen 14
A StringBuffer Java Basics - Anfänger-Themen 1
H Wie wandel ich ein Datum in eine Zeichenkette um mit StringBuffer? Java Basics - Anfänger-Themen 3
S Dateien/LinkedList/StringBuffer - SOrtierung klappt nicht so ganz Java Basics - Anfänger-Themen 2
D Input/Output Stringbuffer Befehle bei Konvertierung in String Java Basics - Anfänger-Themen 19
C Elemente im StringBuffer ersetzen Java Basics - Anfänger-Themen 19
F Problem bei Rückgabe von StringBuffer aus Methode Java Basics - Anfänger-Themen 6
M StringBuffer Java Basics - Anfänger-Themen 2
K Alle vorkommen eines Zeichens in StringBuffer Objekt löschen Java Basics - Anfänger-Themen 6
A String wird nur einmal an den StringBuffer angehängt Java Basics - Anfänger-Themen 10
F StringBuffer und String kompatibel ?? Java Basics - Anfänger-Themen 5
M StringBuffer - Methoden Java Basics - Anfänger-Themen 6
H String/StringBuffer nach zeilen aufteilen Java Basics - Anfänger-Themen 2
M Frage zum StringBuffer Java Basics - Anfänger-Themen 7
A Unterschied zwischen String & Stringbuffer! Java Basics - Anfänger-Themen 14
A Zeichen selektiv in einen neuen StringBuffer speichern Java Basics - Anfänger-Themen 2
S StringBuffer(Buchstabe) -> Double konvertieren Java Basics - Anfänger-Themen 6
K StringBuffer Java Basics - Anfänger-Themen 5
S StringBuffer in Datei - Problem mit neuer Zeile Java Basics - Anfänger-Themen 2
Z Was ist ein StringBuffer und wie benutz ich das Ding? Java Basics - Anfänger-Themen 3
L Streamklassen, Filewriter und StringBuffer Java Basics - Anfänger-Themen 2
S StringBuffer anstatt += Java Basics - Anfänger-Themen 8
D String/StringBuffer mit Zeichen einer Sorte füllen Java Basics - Anfänger-Themen 14
B StringBuffer Problem Java Basics - Anfänger-Themen 2
N String oder StringBuffer/StringBuilder Java Basics - Anfänger-Themen 6
D string/stringbuffer Java Basics - Anfänger-Themen 6
G String vs StringBuffer Java Basics - Anfänger-Themen 11
J StringBuffer-Objekt soll auf Char-Array zugreifen. Java Basics - Anfänger-Themen 4
J StringBuffer Java Basics - Anfänger-Themen 4
T Unicode StringBuffer -> String = unleserlich Java Basics - Anfänger-Themen 7
K Wie kann ich daraus einen StringBuffer machen ? Java Basics - Anfänger-Themen 4
R OutputStream direkt in StringBuffer schreiben lassen Java Basics - Anfänger-Themen 2
L String to StringBuffer Java Basics - Anfänger-Themen 3

Ähnliche Java Themen

Neue Themen


Oben