Différence entre StringBuilder et StringBuffer
Quelle est la principale différence entre StringBuffer
et StringBuilder
?
Est-il des problèmes de rendement au moment de décider sur l'un de ces?
30 réponses
StringBuilder
est plus rapide que StringBuffer
parce que ce n'est pas synchronized
.
voici un simple test de référence:
public class Main {
public static void main(String[] args) {
int N = 77777777;
long t;
{
StringBuffer sb = new StringBuffer();
t = System.currentTimeMillis();
for (int i = N; i --> 0 ;) {
sb.append("");
}
System.out.println(System.currentTimeMillis() - t);
}
{
StringBuilder sb = new StringBuilder();
t = System.currentTimeMillis();
for (int i = N; i > 0 ; i--) {
sb.append("");
}
System.out.println(System.currentTimeMillis() - t);
}
}
}
A test run donne les numéros de 2241 ms
pour StringBuffer
vs 753 ms
pour StringBuilder
.
fondamentalement, StringBuffer
méthodes sont synchronisées tandis que StringBuilder
ne sont pas.
les opérations sont" presque " les mêmes, mais l'utilisation de méthodes synchronisées dans un seul thread est exagérée.
C'est à peu près tout.
citation de StringBuilder API :
cette classe [StringBuilder] fournit une API compatible avec StringBuffer, mais sans garantie de synchronisation . Cette classe est conçue pour être utilisée comme un remplacement direct pour StringBuffer dans les endroits où le tampon de chaîne était utilisé par un seul thread (comme c'est généralement le cas). Dans la mesure du possible, il est recommandé que cette classe soit utilisée de préférence à StringBuffer comme il sera plus rapide sous la plupart des implémentations.
donc il a été fait pour le remplacer.
le même c'est arrivé avec Vector
et ArrayList
.
Mais nécessaire pour obtenir la nette différence avec l'aide d'un exemple?
StringBuffer or StringBuilder
utilisez simplement StringBuilder
à moins que vous n'essayiez vraiment de partager un tampon entre les threads. StringBuilder
est le frère cadet non synchronisé (moins de frais généraux = plus efficace) de la classe originale synchronisée StringBuffer
.
StringBuffer
est arrivé en premier. Sun était préoccupé par l'exactitude dans toutes les conditions, donc ils l'ont synchronisé pour le rendre fil-sûr juste au cas où.
StringBuilder
est venu plus tard. La plupart des utilisations de StringBuffer
ont été à fil simple et payer inutilement le coût de la synchronisation.
depuis StringBuilder
est un remplaçant pour StringBuffer
sans la synchronisation, il n'y aurait pas de différences entre les exemples.
si vous êtes essayer de partager entre les threads, vous pouvez utiliser StringBuffer
, mais examiner si la synchronisation de haut niveau est nécessaire, par exemple peut-être au lieu d'utiliser StringBuffer, si vous synchronisez les méthodes qui utilisent le StringBuilder.
permet D'abord de voir les similitudes : StringBuilder et StringBuffer sont mutables. Cela signifie que vous pouvez changer le contenu de ceux-ci, avec dans le même endroit.
différences : StringBuffer est mutable et synchronisé. Où as StringBuilder est mutable mais pas synchronisé par défaut.
sens de synchronisé (synchronisation) : Quand quelque chose est synchronisé, alors plusieurs threads peuvent accéder, et le modifier sans aucun problème ou effet secondaire. StringBuffer est synchronisé, donc vous pouvez l'utiliser avec plusieurs threads sans aucun problème.
lequel utiliser quand? StringBuilder: quand vous avez besoin d'une chaîne, qui peut être modifiable, et qu'un seul thread y accède et la modifie. StringBuffer: quand vous avez besoin d'une chaîne, qui peut être modifiable, et que plusieurs threads accèdent et modifient il.
Note : N'utilisez pas StringBuffer inutilement, c'est-à-dire ne l'utilisez pas si un seul thread le modifie et y accède parce qu'il a beaucoup de code de verrouillage et de déverrouillage pour la synchronisation qui prendra inutilement du temps CPU. N'utilisez pas de serrures à moins que cela ne soit nécessaire.
en threads simples, StringBuffer n'est pas significativement plus lent que StringBuilder , grâce à des optimisations JVM. Et dans le multithreading, vous ne pouvez pas utiliser en toute sécurité un StringBuilder.
Voici mon 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));
}
Résultats :
cordes: 319740
Tampons : 23
Constructeur: 7 !
Ainsi Les Constructeurs sont plus rapides que les tampons, et beaucoup plus rapides que la concaténation de chaînes. Maintenant, utilisons un exécuteur pour plusieurs 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);
}
}
maintenant StringBuffers prendre 157 ms pour 100000 appends. Ce n'est pas le même test, mais par rapport aux 37 ms précédentes, vous pouvez sans risque supposer que les StringBuffers ajoute sont plus lents avec multithreading utiliser . La raison en est que le JIT/hotspot/compilateur/quelque chose fait optimisations quand il détecte qu'il ya Non besoin de vérifier les serrures.
mais avec StringBuilder, vous avez java.lang.ArrayIndexOutOfBoundsException , parce qu'un thread concurrent essaie d'ajouter quelque chose où il ne devrait pas.
la Conclusion est que vous n'avez pas à poursuivre les Cordbuffers. Et là où vous avez des fils, pensez à ce qu'ils font, avant d'essayer de gagner quelques nanosecondes.
StringBuilder a été introduit en Java 1.5 donc il ne fonctionnera pas avec les JVM précédentes.
De la Javadoc :
StringBuilder class fournit une API compatible avec StringBuffer, mais sans garantie de synchronisation. Cette classe est conçue pour être utilisée comme un remplacement direct pour StringBuffer dans les endroits où le tampon de chaîne était utilisé par un seul thread (comme c'est généralement le cas). Si possible, il est recommandé que cette classe soit utilisée de préférence à StringBuffer car elle sera plus rapide sous la plupart des implémentations.
Assez Bonne Question
Voici les différences, j'ai remarqué:
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.
chose commune: -
ont tous les deux les mêmes méthodes avec les mêmes signatures. Les deux sont mutables.
StringBuilder est pas thread-safe. Le tampon de chaîne est. Complément d'information ici .
EDIT: en ce qui concerne la performance , après hotspot kicks in , StringBuilder est le gagnant. Toutefois , pour les petites itérations, la différence de rendement est négligeable.
StringBuilder
et StringBuffer
sont presque identiques. La différence est que StringBuffer
est synchronisé et StringBuilder
ne l'est pas. Bien que StringBuilder
soit plus rapide que StringBuffer
, la différence de performance est très faible. StringBuilder
est le remplacement de StringBuffer
par un soleil . Il évite juste la synchronisation de toutes les méthodes publiques. Plutôt que cela, leur fonctionnalité est la même.
exemple de bonne utilisation:
si votre texte va changer et est utilisé par plusieurs threads, il est préférable d'utiliser des StringBuffer
. Si votre texte va changer mais est utilisé par un seul thread, alors utilisez StringBuilder
.
StringBuffer
StringBuffer est mutable signifie qu'on peut changer la valeur de l'objet . L'objet créé par StringBuffer est stocké dans le tas . StringBuffer a les mêmes méthodes que le StringBuilder , mais chaque méthode dans StringBuffer est synchronisée ce qui est StringBuffer est thread sûr .
pour cette raison, il ne permet pas à deux threads d'accéder simultanément à la même méthode . Chaque méthode peut être accessible par un seul thread à la fois .
mais être sûr de thread a des inconvénients aussi comme la performance du StringBuffer frappe en raison de la propriété de thread sûr . Ainsi StringBuilder est plus rapide que le StringBuffer quand on appelle les mêmes méthodes de chaque classe.
StringBuffer valeur peut être modifiée , cela signifie qu'il peut être attribué à la nouvelle valeur . Aujourd'hui ,c'est une question d'interview la plus courante, les différences entre les classes ci-dessus . Le tampon de chaîne peut être converti à la chaîne en utilisant la méthode toString ().
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 est le même que le StringBuffer, c'est-à-dire qu'il stocke l'objet dans heap et qu'il peut aussi être modifié . La principale différence entre StringBuffer et StringBuilder est que StringBuilder n'est pas sûr non plus. StringBuilder est rapide car il n'est pas sécurisé .
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
Resource: String Vs StringBuffer Vs StringBuilder
StringBuffer
- synchronisé donc threadsafe
- thread-safe donc lente -
StringBuilder
- introduit en Java 5.0
- asynchrone donc rapide et efficace
- L'utilisateur doit explicitement le synchroniser, s'il le veut
- vous pouvez le remplacer par
StringBuilder
sans aucun autre changement
String
est un immuable.
StringBuffer
est un mutable et synchronisé.
StringBuilder
est également mutable, mais il n'est pas synchronisé.
le javadoc explique la différence:
cette classe fournit une API compatible avec StringBuffer, mais sans garantie de synchronisation. Cette classe est conçue pour être utilisée comme un remplacement direct pour StringBuffer dans les endroits où le tampon de chaîne était utilisé par un seul thread (comme c'est généralement le cas). Dans la mesure du possible, il est recommandé d'utiliser cette classe de préférence à StringBuffer car elle sera plus rapide. dans la plupart des implémentations.
StringBuilder
(introduit en Java 5) est identique à StringBuffer
, sauf que ses méthodes ne sont pas synchronisées. Cela signifie qu'il a de meilleures performances que le dernier, mais l'inconvénient est qu'il n'est pas thread-safe.
Lire tutoriel pour plus de détails.
StringBuilder est beaucoup plus rapide que StringBuffer parce qu'il n'est pas synchronisé.
ici vous avez plus d'idée sur le coût de synchroniser
regardons programmatiquement combien de StringBuilder plus rapide que StringBuffer
public class Test{
public static void main(String[] args){
long startTime = System.currentTimeMillis();
StringBuffer sb = new StringBuffer("Yasir");
for (int i=0; i<10000; i++){
sb.append("Shabbir");
}
System.out.println("Time taken by StringBuffer: " + (System.currentTimeMillis() - startTime) + "ms");
startTime = System.currentTimeMillis();
StringBuilder sb2 = new StringBuilder("Yasir");
for (int i=0; i<10000; i++){
sb2.append("Shabbir");
}
System.out.println("Time taken by StringBuilder: " + (System.currentTimeMillis() - startTime) + "ms");
}
}
Sortie
le Temps pris par StringBuffer: 16ms
le Temps pris par StringBuilder: 0ms
un programme simple illustrant la différence entre StringBuffer et StringBuilder:
/**
* Run this program a couple of times. We see that the StringBuilder does not
* give us reliable results because its methods are not thread-safe as compared
* to StringBuffer.
*
* For example, the single append in StringBuffer is thread-safe, i.e.
* only one thread can call append() at any time and would finish writing
* back to memory one at a time. In contrast, the append() in the StringBuilder
* class can be called concurrently by many threads, so the final size of the
* StringBuilder is sometimes less than expected.
*
*/
public class StringBufferVSStringBuilder {
public static void main(String[] args) throws InterruptedException {
int n = 10;
//*************************String Builder Test*******************************//
StringBuilder sb = new StringBuilder();
StringBuilderTest[] builderThreads = new StringBuilderTest[n];
for (int i = 0; i < n; i++) {
builderThreads[i] = new StringBuilderTest(sb);
}
for (int i = 0; i < n; i++) {
builderThreads[i].start();
}
for (int i = 0; i < n; i++) {
builderThreads[i].join();
}
System.out.println("StringBuilderTest: Expected result is 1000; got " + sb.length());
//*************************String Buffer Test*******************************//
StringBuffer sb2 = new StringBuffer();
StringBufferTest[] bufferThreads = new StringBufferTest[n];
for (int i = 0; i < n; i++) {
bufferThreads[i] = new StringBufferTest(sb2);
}
for (int i = 0; i < n; i++) {
bufferThreads[i].start();
}
for (int i = 0; i < n; i++) {
bufferThreads[i].join();
}
System.out.println("StringBufferTest: Expected result is 1000; got " + sb2.length());
}
}
// Every run would attempt to append 100 "A"s to the StringBuilder.
class StringBuilderTest extends Thread {
StringBuilder sb;
public StringBuilderTest (StringBuilder sb) {
this.sb = sb;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
sb.append("A");
}
}
}
//Every run would attempt to append 100 "A"s to the StringBuffer.
class StringBufferTest extends Thread {
StringBuffer sb2;
public StringBufferTest (StringBuffer sb2) {
this.sb2 = sb2;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
sb2.append("A");
}
}
}
mieux utiliser StringBuilder car il n'est pas synchronisé et donc de meilleures performances. StringBuilder remplace l'Ancien StringBuffer.
StringBuffer
est synchronisé, mais StringBuilder
ne l'est pas. En conséquence, StringBuilder
est plus rapide que StringBuffer
.
StringBuffer est mutable. Il peut changer en termes de longueur et de contenu. StringBuffers sont thread-safe, ce qui signifie qu'ils ont des méthodes synchronisées pour contrôler l'accès de sorte qu'un seul thread peut accéder au Code synchronisé d'un objet StringBuffer à la fois. Ainsi, les objets StringBuffer sont généralement sûrs à utiliser dans un environnement multi-threadé où plusieurs threads peuvent essayer d'accéder au même objet StringBuffer en même temps.
StringBuilder La classe StringBuilder est très similaire à StringBuffer, sauf que son accès n'est pas synchronisé de sorte qu'il n'est pas thread-safe. En n'étant pas synchronisé, la performance de StringBuilder peut être meilleure que StringBuffer. Ainsi, si vous travaillez dans un environnement mono-threadé, L'utilisation de StringBuilder à la place de StringBuffer peut entraîner des performances accrues. Ceci est également vrai dans d'autres situations telles qu'une variable locale StringBuilder (c'est-à-dire une variable dans une méthode) où un seul thread accédera à un objet StringBuilder.
StringBuffer
StringBuffer est mutable signifie qu'on peut changer la valeur de l'objet . L'objet créé par StringBuffer est stocké dans le tas . StringBuffer a les mêmes méthodes que le StringBuilder , mais chaque méthode dans StringBuffer est synchronisée ce qui est StringBuffer est thread sûr .
StringBuilder
StringBuilder est le même que le StringBuffer , c'est-à-dire qu'il stocke l'objet en tas et qu'il peut aussi être modifié . La principale différence entre StringBuffer et StringBuilder est que StringBuilder n'est pas sûr. StringBuilder est rapide car il n'est pas sécurisé .
StringBuffer:
- Multi-Thread
- synchronisé
- Lent que StringBuilder
StringBuilder
- Single-Thread
- Non-Synchronisé
- plus rapide que jamais corde
Chaîne-Builder :
int one = 1;
String color = "red";
StringBuilder sb = new StringBuilder();
sb.append("One=").append(one).append(", Color=").append(color).append('\n');
System.out.print(sb);
// Prints "One=1, Colour=red" followed by an ASCII newline.
Chaîne-Tampon
StringBuffer sBuffer = new StringBuffer("test");
sBuffer.append(" String Buffer");
System.out.println(sBuffer);
il est recommandé d'utiliser StringBuilder autant que possible car il est plus rapide que StringBuffer. Cependant, si la sécurité du thread est nécessaire, la meilleure option est les objets StringBuffer.
StringBuffer est utilisé pour stocker des chaînes de caractères qui seront changées (les objets String ne peuvent pas être changés). Il se développe automatiquement au besoin. Classes apparentées: String, CharSequence.
StringBuilder a été ajouté dans Java 5. Il est identique en tous points à StringBuffer sauf qu'il n'est pas synchronisé, ce qui signifie que si plusieurs threads y accèdent en même temps, il pourrait y avoir des problèmes. Pour les programmes à filetage simple, le cas le plus courant, en évitant la synchronisation au-dessus de nous permet d'accélérer légèrement le StringBuilder.
il n'y a pas de différences fondamentales entre StringBuilder et StringBuffer, seules quelques différences existent entre eux. Dans StringBuffer les méthodes sont synchronisées. Cela signifie qu'à la fois un seul fil peut fonctionner sur eux. S'il y a plus d'un fil, alors le second devra attendre que le premier se termine et le troisième devra attendre que le premier et le second se terminent et ainsi de suite. Cela rend le processus très lent et donc le rendement en cas de StringBuffer est bas.
par contre StringBuilder n'est pas synchronisé. Cela signifie qu'à la fois plusieurs threads peuvent fonctionner sur le même objet StrinBuilder en même temps. Cela rend le processus très rapide et donc la performance de StringBuilder est élevée.
puisque StringBuffer
est synchronisé, il a besoin d'un effort supplémentaire, donc basé sur perforamance, son un peu lent que StringBuilder
.
String est un objet immuable qui signifie que la valeur ne peut pas être changée là où StringBuffer est mutable.
la pince est synchronisée de sorte que le thread safe où comme StringBuilder n'est pas et ne convient que pour les instances filetées simples.
la différence majeure est StringBuffer
est syncronisé mais StringBuilder
ne l'est pas.Si vous avez besoin d'utiliser plus d'un fil , puis StringBuffer est recommandé.Mais, selon la vitesse d'exécution StringBuilder
est plus rapide que StringBuffer
, parce qu'il n'est pas syncronisé .
vérifier les internes de la méthode d'ajout synchronisé de StringBuffer
et de la méthode d'ajout non synchronisé de StringBuilder
.
public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}
public synchronized StringBuffer append(Object obj) {
super.append(String.valueOf(obj));
return this;
}
public synchronized StringBuffer append(String str) {
super.append(str);
return this;
}
public StringBuilder(String str) {
super(str.length() + 16);
append(str);
}
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
public StringBuilder append(String str) {
super.append(str);
return this;
}
depuis l'ajout est synchronized
, StringBuffer
a la performance aérienne par rapport à StrinbBuilder
dans le scénario de multi-filetage. Tant que vous ne partagez pas le tampon parmi les fils multiples, utilisez StringBuilder
, qui est rapide en raison de l'absence de synchronized
dans les méthodes d'ajout.
ce lien vous permettra de comprendre non seulement les concepts de StringBuilder
et StringBuffer
mais aussi leur association et différence avec la classe String
. Cela vous fera comprendre quand utiliser quelle classe.
http://www.acquireandinspire.org/2013/01/string-string-builder-string-buffer.html