Question

Quelle est la principale différence entre et StringBuffer StringBuilder? Y at-il des problèmes de performance au moment de décider sur l'un de ces?

Était-ce utile?

La solution

StringBuffer est synchronisée, n'est pas StringBuilder.

Autres conseils

est plus rapide StringBuilder 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);
        }
    }
}

test donne le nombre de 2241 ms pour vs 753 ms pour <=> <=> .

Fondamentalement, StringBuffer méthodes sont synchronisés tandis que StringBuilder ne sont pas.

Les opérations sont « presque » les mêmes, mais en utilisant des méthodes synchronisées dans un seul thread est surpuissant.

C'est à peu près à ce sujet.

Citation de StringBuilder API :

  

Cette classe [StringBuilder] fournit une API compatible avec StringBuffer, mais sans garantie de synchronisation . Cette classe est conçu pour être utilisé en remplacement de drop-in pour StringBuffer dans des endroits où la mémoire tampon de chaîne a été utilisée par un seul fil (comme cela est généralement le cas). Lorsque cela est possible, il est recommandé que cette classe soit utilisée de préférence à StringBuffer il sera plus rapide dans la plupart des mises en œuvre.

Il a été fait pour le remplacer.

La même chose est arrivée avec et Vector ArrayList.

  

Mais nécessaire pour obtenir la nette différence avec l'aide d'un exemple?

     

StringBuffer ou StringBuilder

Utilisez simplement StringBuilder à moins que vous essayez vraiment de partager un tampon entre les threads. Est le désynchronisé StringBuffer (moins de frais généraux = plus efficace) frère cadet de la classe originale synchronisée <=>.

<=> est venu en premier. Sun a été préoccupé par exactitude dans toutes les conditions, alors ils l'ont fait synchronisé pour le rendre thread-safe juste au cas où.

<=> est venu plus tard. La plupart des utilisations de simple étaient <=> fil et payer inutilement le coût de la synchronisation.

Depuis est un <=> remplacement drop-in pour la synchronisation sans <=>, il n'y aurait pas de différences entre les exemples.

Si vous sont tente de partager entre les fils, vous pouvez utiliser <=>, mais déterminer si la synchronisation de niveau supérieur est nécessaire, par exemple peut-être au lieu d'utiliser StringBuffer, si vous synchroniser les méthodes qui utilisent le StringBuilder.

Tout d'abord permet de voir les similitudes : Les deux StringBuilder et StringBuffer sont mutables. Cela signifie que vous pouvez modifier le contenu d'entre eux, avec dans le même endroit.

Différences : StringBuffer est mutable et synchronisé ainsi. Où que StringBuilder est mutable mais non synchronisée par défaut.

Sens de synchronisation (synchronisation) : Quand quelque chose est synchronisé, puis plusieurs threads peuvent accéder et modifier à tout effet de problème ou sur le côté. StringBuffer est synchronisé, vous pouvez l'utiliser avec plusieurs threads avec tout problème.

Lequel utiliser quand? StringBuilder: Lorsque vous avez besoin d'une chaîne, qui peut être modifiable, et un seul fil est l'accès et la modifier. StringBuffer. Lorsque vous avez besoin d'une chaîne, qui peut être modifiable, et plusieurs threads accès et la modifier

Remarque : Ne pas utiliser StringBuffer inutilement, par exemple, ne l'utilisez pas si un seul thread est la modification et l'accès parce qu'il a beaucoup de verrouillage et déverrouillage du code pour la synchronisation qui inutilement prendre le temps CPU. Ne pas utiliser des verrous moins qu'il ne soit nécessaire.

fils simples, StringBuffer est pas significativement plus lente que StringBuilder , grâce à des optimisations JVM. Et en multithreading, vous ne pouvez pas utiliser en toute sécurité un StringBuilder.

Voici mon test (pas de référence, juste un 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
Buffers: 23 Constructeur: 7

Alors les constructeurs sont plus rapides que buffers, et plus vite que les chaînes WAY concaténation. Maintenant, nous allons utiliser 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);
    }
}

157 ms pour 100000 ajouter ses. Ce n'est pas le même test, mais par rapport aux 37 ms précédentes, vous pouvez supposer que StringBuffers sont plus lents à ajouter ses utilisation multithreading . La raison en est que le JIT / hotspot / compilateur / quelque chose fait des optimisations quand il détecte qu'il ya pas besoin de vérifier les serrures .

Mais 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 à chasser StringBuffers. Et 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 JVMs plus tôt.

De la Javadocs :

  

classe StringBuilder fournit une API compatible avec StringBuffer, mais sans garantie de synchronisation. Cette classe est conçu pour être utilisé en remplacement de drop-in pour StringBuffer dans des endroits où la mémoire tampon de chaîne a été utilisée par un seul fil (comme cela est généralement le cas). Lorsque cela est possible, il est recommandé que cette classe soit utilisée de préférence à StringBuffer car il sera plus rapide dans la plupart des mises en œuvre.

  

Pretty Good Question

Voici les différences, je l'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: -

  

Les deux ont les mêmes méthodes avec les signatures mêmes. Les deux sont mutables.

StringBuilder est pas thread-safe. Chaîne tampon est. Plus d'infos ici .

EDIT: En ce qui concerne la performance, après entre en jeu, StringBuilder est le gagnant. Cependant, pour les petites itérations, la différence de performance est négligeable.

StringBuilder et sont presque StringBuffer même. La différence est que Synchronisé et est <=> n'est pas <=>. Bien que, est plus rapide que <=> <=>, la différence de performance est très peu. Est un <=> remplacement de SUN de <=>. Il évite que la synchronisation de toutes les méthodes publiques. Au lieu de cela, leur fonctionnalité est la même.

Exemple de bon usage:

Si votre texte va changer et est utilisé par plusieurs threads, il est préférable d'utiliser <=>. Si votre texte va changer, mais est utilisé par un seul fil, puis utilisez <=>.

StringBuffer

  • donc Synchronisé threadsafe
  • thread-safe donc lent

StringBuilder

  • Introduit en Java 5.0
  • Asynchronous donc rapide et efficace
  • L'utilisateur doit explicitement synchroniser, s'il veut
  • Vous pouvez le remplacer par tout autre sans <=> changement

StringBuffer

StringBuffer est mutable signifie qu'on peut modifier 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é qui est StringBuffer est thread-safe.

à cause de cela, il ne permet pas deux threads d'accéder simultanément la même méthode. Chacune de ces méthodes peut être consulté par un fil à la fois.

Mais étant sûr de fil a aussi des inconvénients que la performance du StringBuffer frappe à cause de fil bien sûr. Ainsi StringBuilder est plus rapide que le StringBuffer lorsque vous appelez les mêmes méthodes de chaque classe.

valeur StringBuffer peut être changé, cela signifie qu'il peut être affecté à la nouvelle valeur. De nos jours, la question de l'entrevue la plus courante, les différences entre les classes ci-dessus. Chaîne tampon peut être converti en la chaîne en utilisant Procédé 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 la même que StringBuffer, qui est il stocke l'objet en tas et il peut également être modifié. La principale différence entre le StringBuffer et StringBuilder est que StringBuilder est pas non thread-safe. StringBuilder est rapide car il est pas thread-safe.

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

 ici

Ressources: Chaîne Vs StringBuffer Vs StringBuilder

String est un immuable.

StringBuffer est un mutable et synchronisée.

StringBuilder est également mutable mais son non synchronisé.

Le javadoc explique la différence:

  

Cette classe fournit une API compatible avec StringBuffer, mais sans garantie de synchronisation. Cette classe est conçu pour être utilisé en remplacement de drop-in pour StringBuffer dans des endroits où la mémoire tampon de chaîne a été utilisée par un seul fil (comme cela est généralement le cas). Lorsque cela est possible, il est recommandé que cette classe soit utilisée de préférence à StringBuffer car il sera plus rapide dans la plupart des implémentations.

StringBuilder (introduit en Java 5) est identique à StringBuffer, à l'exception de ses méthodes ne sont pas synchronisés. Cela signifie qu'il a de meilleures performances que celui-ci, mais l'inconvénient est que ce n'est pas thread-safe.

Lire tutoriel pour plus de détails.

Un programme simple qui illustre 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");
        }

    }
}

Une meilleure utilisation StringBuilder car il est pas synchronisé et par conséquent une meilleure performance. StringBuilder est une fonction de remplacement dans des StringBuffer plus.

StringBuffer est synchronisé, mais n'est pas StringBuilder. Par conséquent, est plus rapide que <=> <=>.

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 de synchronisation d'un objet StringBuffer à la fois. Ainsi, les objets StringBuffer sont généralement sans danger à 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 ne soit pas synchronisé afin qu'il ne soit pas thread-safe. En ne sont pas synchronisés, la performance de StringBuilder peut être mieux que StringBuffer. Ainsi, si vous travaillez dans un environnement mono-thread, en utilisant StringBuilder au lieu de StringBuffer peut entraîner une augmentation des performances. Ceci est également vrai pour d'autres situations, comme une variable locale StringBuilder (c.-à-une variable dans une méthode) où un seul thread sera accéder à un objet StringBuilder.

StringBuffer:

  • Multi-fil
  • Synchronisé
  • lent que StringBuilder

StringBuilder

  • monothread
  • Non-Synchronisé
  • Plus rapide que jamais chaîne

String-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.

String-tampon

StringBuffer sBuffer = new StringBuffer("test");
sBuffer.append(" String Buffer");
System.out.println(sBuffer);  

Il est recommandé d'utiliser StringBuilder chaque fois que possible, car il est plus rapide que StringBuffer. Toutefois, si la sécurité de fil est nécessaire, la meilleure option est des objets StringBuffer.

StringBuffer est utilisé pour les chaînes de caractères magasin qui seront modifiés (objets chaîne ne peut pas être changé). Il étend automatiquement au besoin. classes associées:. String, CharSequence

StringBuilder a été ajouté en Java 5. Il est identique à tous égards à StringBuffer, sauf qu'il ne soit pas synchronisé, ce qui signifie que si plusieurs threads accèdent en même temps, il pourrait y avoir des problèmes. Pour les programmes monothread, le cas le plus courant, ce qui évite la surcharge de synchronisation rend le StringBuilder très légèrement plus rapide.

Il n'y a pas différences fondamentales entre StringBuilder et StringBuffer, quelques différences existent entre eux. En StringBuffer les méthodes sont synchronisées. Cela signifie que, à un moment un seul thread peut fonctionner sur eux. S'il y a plus d'un fil alors le deuxième fil devra attendre le premier à terminer et le troisième devra attendre le premier et deuxième à la fin et ainsi de suite. Cela rend le processus très lent et par conséquent les performances en cas de StringBuffer est faible.

Par contre StringBuilder est non synchronisé. Cela signifie que à 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é.

Depuis est synchronisé StringBuffer, il a besoin d'un effort supplémentaire, donc basée sur la performance, est un peu lent que StringBuilder.

chaîne est un objet immuable qui signifie que la valeur ne peut être modifiée alors que StringBuffer est mutable.

Le StringBuffer est donc Synchronisé fil sûr où que StringBuilder n'est pas et approprié pour les cas que seul thread.

La principale différence est est StringBuffer mais synchronisée est not.If vous StringBuilder besoin d'utiliser plus d'un fil, puis StringBuffer est recommended.But, selon la vitesse d'exécution est plus rapide que <=> <=> , parce que son pas Syncronisées.

Vérifier le fonctionnement interne du procédé d'ajout synchronisé de StringBuffer et un procédé d'ajout non-synchronisée de StringBuilder.

StringBuffer :

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;
}

StringBuilder :

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 append est synchronized, a en tête de StrinbBuilder performance par rapport à scénario dans plusieurs <=>-threading. Tant que vous ne partagez pas tampon entre plusieurs threads, utilisez <=>, ce qui est rapide en raison de l'absence de méthodes de <=> append.

Voici le résultat de tests de performance pour Chaîne vs vs StringBuffer StringBuilder . Enfin, StringBuilder a gagné l'épreuve. Voir ci-dessous pour le code de test et le résultat.

code :

private static void performanceTestStringVsStringbuffereVsStringBuilder() {
// String vs StringBiffer vs StringBuilder performance Test

int loop = 100000;
long start = 0;

// String
String str = null;
start = System.currentTimeMillis();
for (int i = 1; i <= loop; i++) {
  str += i + "test";
}
System.out.println("String - " + (System.currentTimeMillis() - start) + " ms");

// String buffer
StringBuffer sbuffer = new StringBuffer();
start = System.currentTimeMillis();
for (int i = 1; i <= loop; i++) {
  sbuffer.append(i).append("test");
}
System.out.println("String Buffer - " + (System.currentTimeMillis() - start) + " ms");

// String builder
start = System.currentTimeMillis();
StringBuilder sbuilder = new StringBuilder();
for (int i = 1; i <= loop; i++) {
  sbuffer.append(i).append("test");
}
System.out.println("String Builder - " + (System.currentTimeMillis() - start) + " ms");

  }

me exécuter sur ideone

Résultat :

100000 itération pour l'ajout d'un texte unique

String - 37489 ms
String Buffer - 5 ms
String Builder - 4 ms

10000 itération pour l'ajout d'un texte unique

String - 389 ms
String Buffer - 1 ms
String Builder - 1 ms
  • StringBuffer est thread-safe, mais StringBuilder est pas thread-safe.
  • StringBuilder est plus rapide que StringBuffer.
  • StringBuffer est synchronisé alors que StringBuilder n'est pas synchronisée.

Chaque présente méthode StringBuffer est synchronisé. donc à la fois un seul thread est autorisé à faire fonctionner l'objet StringBuffer. Il augmente le temps d'attente d'un fil et crée des problèmes de performance pour surmonter ce problème SUN Personnes StringBuilder dans 1,5 volontairement introduites la version.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top