Löschen eines Zeichenfolgenpuffers/Builders nach der Schleife

Lesezeit: 7 Minuten

Benutzer-Avatar
Wasserfallregen

Wie löschen Sie den String-Puffer in Java nach einer Schleife, damit die nächste Iteration einen leeren String-Puffer verwendet?

  • Eine andere Frage: Warum verwenden Sie einen SB nur für eine Iteration der Schleife? Gibt es eine weitere innere Iteration? SB ist nicht würdig, wenn Sie einfach A + B + C + D ausführen möchten (Java-Compiler verwendet intern ein SB). Es hilft, wenn Sie Teile von Zeichenfolgen bedingt hinzufügen möchten, aber ansonsten … verwenden Sie einfach “+”.

    – helios

    11. Februar 2010 um 9:09 Uhr

Benutzer-Avatar
Jon

Eine Möglichkeit besteht darin, die delete-Methode wie folgt zu verwenden:

StringBuffer sb = new StringBuffer();
for (int n = 0; n < 10; n++) {
   sb.append("a");

   // This will clear the buffer
   sb.delete(0, sb.length());
}

Eine andere Option (Bit Cleaner) verwendet setLength(int Länge):

sb.setLength(0);

Sehen Javadoc Für mehr Information:

  • Etwas weniger Müll wäre, den StringBuffer einfach innerhalb der Schleife zu deklarieren.

    – Markus Elliot

    11. Februar 2010 um 5:33 Uhr

  • Ah, ich denke sb.setLength(0); ist sauberer und effizienter als die Deklaration innerhalb der Schleife. Ihre Lösung widerspricht dem Leistungsvorteil der Verwendung von StringBuffer …

    – Jon

    11. Februar 2010 um 5:38 Uhr

  • Ich denke, der Leistungsvorteil ergibt sich aus der String-Veränderlichkeit, nicht aus dem Speichern der Instanziierung. Hier ist ein schneller Test von 1e8-Iterationen: Inside Loop (2,97 s): ideone.com/uyyTL14wäußere Schleife (2,87 s): ideone.com/F9lgsIxh

    – Markus Elliot

    11. Februar 2010 um 5:46 Uhr


  • Apropos Leistung: Sofern auf Ihren Code nicht in einem Multithread-Szenario zugegriffen wird, sollten Sie StringBuilder anstelle von StringBuffer verwenden – siehe javadoc: die meisten Implementierungen”.

    – Rahel Lüthy

    11. Februar 2010 um 7:53 Uhr

  • Der einzige Vorteil der Erstellung des SB außerhalb besteht darin, dass das interne (möglicherweise lange) Zeichen nicht verloren geht[] davon. Wenn es im ersten Iterator groß genug geworden ist, muss die zweite Schleife kein Zeichen in der Größe ändern[]. Aber um den Vorteil zu erzielen, muss die “Clear-Methode” die Größe des internen Arrays beibehalten. setLength macht das, aber es setzt auch alle nicht verwendeten Zeichen im SB auf \u0000, also ist es weniger performant, als einfach ein neues SB mit einer guten Anfangskapazität zu erstellen. Deklarieren innerhalb der Schleife ist besser.

    – helios

    11. Februar 2010 um 9:08 Uhr

Benutzer-Avatar
Mossaddeque Mahmood

Der einfachste Weg, die wiederzuverwenden StringBuffer ist die Methode anzuwenden setLength()

public void setLength(int newLength)

Vielleicht haben Sie den Fall mögen

StringBuffer sb = new StringBuffer("HelloWorld");
// after many iterations and manipulations
sb.setLength(0);
// reuse sb

  • @MMahmoud, Im Codebeispiel sollte es lauten setLength Anstatt von setlength.

    – Onabai

    7. Dezember 2012 um 15:58 Uhr

  • Wie funktioniert es, wenn ich die setLength-Codequelle sehe (gist.github.com/ebuildy/e91ac6af2ff8a6b1821d18abf2f8c9e1) hier wird count immer größer sein als newLength (0) ?

    – Thomas Decaux

    2. November 2018 um 19:20 Uhr


Sie haben zwei Möglichkeiten:

Verwenden Sie entweder:

sb.setLength(0);  // It will just discard the previous data, which will be garbage collected later.  

Oder verwenden Sie:

sb.delete(0, sb.length());  // A bit slower as it is used to delete sub sequence.  

HINWEIS

Verzichten Sie auf eine Deklaration StringBuffer oder StringBuilder Objekte innerhalb der Schleife, sonst werden bei jeder Iteration neue Objekte erstellt. Das Erstellen von Objekten erfordert Systemressourcen, Speicherplatz und nimmt auch Zeit in Anspruch. Vermeiden Sie es also auf lange Sicht, sie innerhalb einer Schleife zu deklarieren, wenn möglich.

Benutzer-Avatar
Ido Keßler

public void clear(StringBuilder s) {
    s.setLength(0);
}

Verwendungszweck:

StringBuilder v = new StringBuilder();
clear(v);

Für die Lesbarkeit denke ich, dass dies die beste Lösung ist.

Ich schlage vor, eine neue zu erstellen StringBuffer (oder noch besser StringBuilder) für jede Iteration. Der Leistungsunterschied ist wirklich vernachlässigbar, aber Ihr Code wird kürzer und einfacher.

  • Wenn Sie Beweise für einen solchen Leistungsunterschied haben, teilen Sie ihn bitte mit. (Ich freue mich auch über Statistiken darüber, wo Java am häufigsten verwendet wird und unter welcher Definition von “meistens”.)

    – Eli Acherkan

    26. November 2015 um 11:07 Uhr

  • Es ist bekannt, dass die Zuordnung (Schlüsselwort new in Java) teurer ist, als nur einige Felder desselben Objekts zu ändern. Für “meistens”, das Sie mit hoch ersetzen könnten, gibt es mehr als 1,5 Milliarden Android-Geräte, die alle Java verwenden.

    – Ludwig CAD

    26. November 2015 um 11:17 Uhr

  • Ich stimme zu, dass in einigen Fällen die Lesbarkeit des Codes wichtiger ist als die Leistung, aber in diesem Fall ist es nur eine Codezeile! Und Sie können einen Benchmark ausführen, der Ihnen beweist, dass die Zuweisung und Objekterstellung sowie das Sammeln von Datenmüll teurer sind, als es überhaupt nicht zu tun. Da wir uns in einer Schleife befinden, ist es mehr als relevant.

    – Ludwig CAD

    26. November 2015 um 14:17 Uhr

  • Ich habe mich auch Knuths Ansicht angeschlossen, aber seine Ansicht ist nicht immer richtig. Hinzufügen nur eine Zeile potenziell CPU-Zyklen und Speicher zu gewinnen, ist absolut nicht böse. Du nimmst die Idee zu direkt. Beachten Sie, dass eine Schleife normalerweise viele Male wiederholt wird. Eine Schleife kann tausende Male wiederholt werden, was bei nicht sorgfältiger Optimierung wertvolle Megabytes auf einem Mobiltelefon (und auch auf einem Server oder Computer) verschlingen kann.

    – Ludwig CAD

    26. November 2015 um 15:52 Uhr

  • Ich denke, wir haben beide unsere Standpunkte klar genug zum Ausdruck gebracht, und ich denke, dass eine weitere Diskussion für diesen Kommentarabschnitt nicht von Vorteil sein wird. Wenn Sie der Meinung sind, dass meine Antwort falsch, irreführend oder unvollständig ist, können Sie – oder jeder andere – sie auf jeden Fall bearbeiten und / oder ablehnen.

    – Eli Acherkan

    26. November 2015 um 16:01 Uhr

Benutzer-Avatar
Suraj Chandran

buf.delete(0,  buf.length());

  • Wenn Sie Beweise für einen solchen Leistungsunterschied haben, teilen Sie ihn bitte mit. (Ich freue mich auch über Statistiken darüber, wo Java am häufigsten verwendet wird und unter welcher Definition von “meistens”.)

    – Eli Acherkan

    26. November 2015 um 11:07 Uhr

  • Es ist bekannt, dass die Zuordnung (Schlüsselwort new in Java) teurer ist, als nur einige Felder desselben Objekts zu ändern. Für “meistens”, das Sie mit hoch ersetzen könnten, gibt es mehr als 1,5 Milliarden Android-Geräte, die alle Java verwenden.

    – Ludwig CAD

    26. November 2015 um 11:17 Uhr

  • Ich stimme zu, dass in einigen Fällen die Lesbarkeit des Codes wichtiger ist als die Leistung, aber in diesem Fall ist es nur eine Codezeile! Und Sie können einen Benchmark ausführen, der Ihnen beweist, dass die Zuweisung und Objekterstellung sowie das Sammeln von Datenmüll teurer sind, als es überhaupt nicht zu tun. Da wir uns in einer Schleife befinden, ist es mehr als relevant.

    – Ludwig CAD

    26. November 2015 um 14:17 Uhr

  • Ich habe mich auch Knuths Ansicht angeschlossen, aber seine Ansicht ist nicht immer richtig. Hinzufügen nur eine Zeile potenziell CPU-Zyklen und Speicher zu gewinnen, ist absolut nicht böse. Du nimmst die Idee zu direkt. Beachten Sie, dass eine Schleife normalerweise viele Male wiederholt wird. Eine Schleife kann tausende Male wiederholt werden, was bei nicht sorgfältiger Optimierung wertvolle Megabytes auf einem Mobiltelefon (und auch auf einem Server oder Computer) verschlingen kann.

    – Ludwig CAD

    26. November 2015 um 15:52 Uhr

  • Ich denke, wir haben beide unsere Standpunkte klar genug zum Ausdruck gebracht, und ich denke, dass eine weitere Diskussion für diesen Kommentarabschnitt nicht von Vorteil sein wird. Wenn Sie der Meinung sind, dass meine Antwort falsch, irreführend oder unvollständig ist, können Sie – oder jeder andere – sie auf jeden Fall bearbeiten und / oder ablehnen.

    – Eli Acherkan

    26. November 2015 um 16:01 Uhr

Benutzer-Avatar
Hao

Schon gute Antwort dort. Fügen Sie einfach ein Benchmark-Ergebnis für den Leistungsunterschied von StringBuffer und StringBuild hinzu, verwenden Sie eine neue Instanz in der Schleife oder verwenden Sie setLength(0) in der Schleife.

Die Zusammenfassung lautet: In einer großen Schleife

  • StringBuilder ist viel schneller als StringBuffer
  • Neue StringBuilder-Instanz in Schleife erstellen hat keinen Unterschied zu setLength(0). (setLength(0) hat einen sehr, sehr, sehr kleinen Vorteil, als eine neue Instanz zu erstellen.)
  • StringBuffer ist langsamer als StringBuilder, indem eine neue Instanz in einer Schleife erstellt wird
  • setLength(0) von StringBuffer ist extrem langsamer als das Erstellen einer neuen Instanz in einer Schleife.

Sehr einfacher Benchmark (ich habe den Code nur manuell geändert und verschiedene Tests durchgeführt):

public class StringBuilderSpeed {
public static final char ch[] = new char[]{'a','b','c','d','e','f','g','h','i'};

public static void main(String a[]){
    int loopTime = 99999999;
    long startTime = System.currentTimeMillis();
    StringBuilder sb = new StringBuilder();
    for(int i = 0 ; i < loopTime; i++){
        for(char c : ch){
            sb.append(c);
        }
        sb.setLength(0);
    }
    long endTime = System.currentTimeMillis();
    System.out.println("Time cost: " + (endTime - startTime));
}

}

Neue StringBuilder-Instanz in Schleife: Zeitaufwand: 3693, 3862, 3624, 3742

StringBuilder setLänge: Zeitaufwand: 3465, 3421, 3557, 3408

Neue StringBuffer-Instanz in Schleife: Zeitaufwand: 8327, 8324, 8284

StringBuffer setLength Zeitkosten: 22878, 23017, 22894

Wieder StringBuilder setLength, um sicherzustellen, dass mein Labtop kein Problem hat, so lange für StringBuffer setLength zu verwenden 🙂 Zeitaufwand: 3448

1334850cookie-checkLöschen eines Zeichenfolgenpuffers/Builders nach der Schleife

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy