Was ist der Hauptunterschied zwischen StringBuffer
y StringBuilder
? Gibt es irgendwelche Leistungsprobleme, wenn man sich für eines dieser Produkte entscheidet?
Antworten
Zu viele Anzeigen?In einzelnen Fäden, StringBuffer ist nicht wesentlich langsamer als StringBuilder dank der JVM-Optimierungen. Und in Multithreading, können Sie nicht sicher einen StringBuilder verwenden.
Hier ist mein Test (kein Benchmark, nur ein Test):
public static void main(String[] args) {
String withString ="";
long t0 = System.currentTimeMillis();
for (int i = 0 ; i < 100000; i++){
withString+="some string";
}
System.out.println("strings:" + (System.currentTimeMillis() - t0));
t0 = System.currentTimeMillis();
StringBuffer buf = new StringBuffer();
for (int i = 0 ; i < 100000; i++){
buf.append("some string");
}
System.out.println("Buffers : "+(System.currentTimeMillis() - t0));
t0 = System.currentTimeMillis();
StringBuilder building = new StringBuilder();
for (int i = 0 ; i < 100000; i++){
building.append("some string");
}
System.out.println("Builder : "+(System.currentTimeMillis() - t0));
}
Ergebnisse:
Streicher: 319740
Puffer : 23
Erbauer : 7 !
Builder sind also schneller als Puffer und VIEL schneller als die Verkettung von Zeichenketten. Verwenden wir nun einen Testamentsvollstrecker für mehrere Threads :
public class StringsPerf {
public static void main(String[] args) {
ThreadPoolExecutor executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
//With Buffer
StringBuffer buffer = new StringBuffer();
for (int i = 0 ; i < 10; i++){
executorService.execute(new AppendableRunnable(buffer));
}
shutdownAndAwaitTermination(executorService);
System.out.println(" Thread Buffer : "+ AppendableRunnable.time);
//With Builder
AppendableRunnable.time = 0;
executorService = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);
StringBuilder builder = new StringBuilder();
for (int i = 0 ; i < 10; i++){
executorService.execute(new AppendableRunnable(builder));
}
shutdownAndAwaitTermination(executorService);
System.out.println(" Thread Builder: "+ AppendableRunnable.time);
}
static void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // code reduced from Official Javadoc for Executors
try {
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow();
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (Exception e) {}
}
}
class AppendableRunnable<T extends Appendable> implements Runnable {
static long time = 0;
T appendable;
public AppendableRunnable(T appendable){
this.appendable = appendable;
}
@Override
public void run(){
long t0 = System.currentTimeMillis();
for (int j = 0 ; j < 10000 ; j++){
try {
appendable.append("some string");
} catch (IOException e) {}
}
time+=(System.currentTimeMillis() - t0);
}
}
Jetzt nehmen StringBuffers 157 ms für 100000 Anhänge. Es ist nicht derselbe Test, aber im Vergleich zu den vorherigen 37 ms können Sie sicher davon ausgehen, dass StringBuffers appends sind langsamer bei Multithreading Verwendung . Der Grund dafür ist, dass der JIT/Hotspot/Compiler/etwas Optimierungen vornimmt, wenn er feststellt, dass es eine keine Notwendigkeit der Überprüfung von Schlössern.
Pero mit StringBuilder, haben Sie java.lang.ArrayIndexOutOfBoundsException weil ein gleichzeitiger Thread versucht, etwas hinzuzufügen, was er nicht sollte.
Die Schlussfolgerung ist, dass man StringBuffers nicht jagen muss. Und wenn Sie Threads haben, denken Sie darüber nach, was sie tun, bevor Sie versuchen, ein paar Nanosekunden zu gewinnen.
StringBuilder wurde in Java 1.5 eingeführt und funktioniert daher nicht mit früheren JVMs.
Von der Javadocs :
Die Klasse StringBuilder bietet eine API, die mit StringBuffer kompatibel ist, aber keine Garantie für die Synchronisierung bietet. Diese Klasse ist als Ersatz für StringBuffer gedacht, wenn der String-Buffer von einem einzigen Thread verwendet wird (was im Allgemeinen der Fall ist). Wenn möglich, wird empfohlen, dass diese Klasse anstelle von StringBuffer verwendet wird, da sie bei den meisten Implementierungen schneller ist.
Ziemlich gute Frage
Hier sind die Unterschiede, die ich festgestellt habe:
StringBuffer :-
StringBuffer is synchronized
StringBuffer is thread-safe
StringBuffer is slow (try to write a sample program and execute it, it will take more time than StringBuilder)
StringBuilder:-
StringBuilder is not synchronized
StringBuilder is not thread-safe
StringBuilder performance is better than StringBuffer.
Gemeinsame Sache :-
Beide haben dieselben Methoden mit denselben Signaturen. Beide sind veränderbar.
StringBuffer
StringBuffer ist veränderbar, d.h. man kann den Wert des Objekts ändern. Das durch StringBuffer erzeugte Objekt wird im Heap gespeichert. StringBuffer hat die gleichen Methoden wie der StringBuilder, aber jede Methode in StringBuffer ist synchronisiert, d.h. StringBuffer ist thread safe.
Deshalb ist es nicht möglich, dass zwei Threads gleichzeitig auf dieselbe Methode zugreifen. Auf jede Methode kann jeweils nur von einem Thread zugegriffen werden.
Die Threadsicherheit hat jedoch auch Nachteile, da die Leistung des StringBuffers aufgrund der Threadsicherheitseigenschaft leidet. Daher ist der StringBuilder schneller als der StringBuffer, wenn die gleichen Methoden der beiden Klassen aufgerufen werden.
StringBuffer-Wert kann geändert werden, d.h. er kann dem neuen Wert zugewiesen werden. Heutzutage ist es eine häufig gestellte Frage im Interview, die Unterschiede zwischen den oben genannten Klassen. String Buffer kann in eine Zeichenkette umgewandelt werden, indem man die toString() Methode umgewandelt werden.
StringBuffer demo1 = new StringBuffer(“Hello”) ;
// The above object stored in heap and its value can be changed .
demo1=new StringBuffer(“Bye”);
// Above statement is right as it modifies the value which is allowed in the StringBuffer
StringBuilder
StringBuilder ist das gleiche wie die StringBuffer, das heißt, es speichert das Objekt in Heap und es kann auch geändert werden. Der Hauptunterschied zwischen dem StringBuffer und dem StringBuilder besteht darin, dass der StringBuilder ebenfalls nicht thread-sicher ist. Der StringBuilder ist schnell, da er nicht thread-sicher ist.
StringBuilder demo2= new StringBuilder(“Hello”);
// The above object too is stored in the heap and its value can be modified
demo2=new StringBuilder(“Bye”);
// Above statement is right as it modifies the value which is allowed in the StringBuilder
Ressource: String Vs StringBuffer Vs StringBuilder