example - stringbuilder java 8




Différence entre StringBuilder et StringBuffer (20)

Quelle est la principale différence entre StringBuffer et StringBuilder ? Y a-t-il des problèmes de performance au moment de prendre une décision?


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 banale :-

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


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

StringBuffer ou StringBuilder

Utilisez simplement StringBuilder sauf si vous essayez vraiment de partager un tampon entre les threads. StringBuilder est le petit frère non synchronisé (moins de surcharge = plus efficace) de la classe StringBuffer synchronisée d'origine.

StringBuffer est arrivé en premier. Sun était soucieux de l'exactitude dans toutes les conditions, donc ils l'ont fait synchroniser pour le rendre sûr au fil du fil au cas où.

StringBuilder est venu plus tard. La plupart des utilisations de StringBuffer étaient mono-thread et payaient inutilement le coût de la synchronisation.

Puisque StringBuilder est un remplacement de StringBuffer sans la synchronisation, il n'y aurait pas de différences entre les exemples.

Si vous essayez de partager entre threads, vous pouvez utiliser StringBuffer , mais pensez à la nécessité d'une synchronisation de niveau supérieur, par exemple, au lieu d'utiliser StringBuffer, si vous synchronisez les méthodes qui utilisent StringBuilder.


D'abord, voyons les similitudes : StringBuilder et StringBuffer sont mutables. Cela signifie que vous pouvez en changer le contenu au même endroit.

Différences : StringBuffer est mutable et synchronisé aussi. Où StringBuilder est mutable mais pas synchronisé par défaut.

Signification 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é, vous pouvez donc l'utiliser avec plusieurs threads sans problème.

Lequel utiliser quand? StringBuilder: Lorsque vous avez besoin d'une chaîne, qui peut être modifiable, et qu'un seul thread l'accède et la modifie. StringBuffer: lorsque vous avez besoin d'une chaîne, qui peut être modifiable, et que plusieurs threads y accèdent et la modifient.

Remarque : N'utilisez pas StringBuffer inutilement, c'est-à-dire ne l'utilisez pas si un seul thread est en train de modifier et d'y accéder car il a beaucoup de code de verrouillage et de déverrouillage qui prend inutilement du temps CPU. N'utilisez pas de verrous sauf si cela est nécessaire.


Dans les threads simples, StringBuffer n'est pas significativement plus lent que StringBuilder , grâce aux optimisations JVM. Et en 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!

Donc, les constructeurs sont plus rapides que les tampons, et WAY plus rapide que la concaténation des chaînes. Utilisons maintenant un Executor 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 prend 157 ms pour 100000 ajouts. Ce n'est pas le même test, mais comparé aux 37 ms précédents, vous pouvez supposer que les extensions StringBuffers sont plus lentes avec l'utilisation du multithreading . La raison en est que le JIT / hotspot / compilateur / quelque chose fait des optimisations quand il détecte qu'il n'est pas nécessaire de vérifier les verrous.

Mais avec StringBuilder, vous avez java.lang.ArrayIndexOutOfBoundsException , car un thread concurrent tente d'ajouter quelque chose là où il ne devrait pas.

Conclusion: vous n'avez pas besoin de chasser StringBuffers. Et là où vous avez des discussions, pensez à ce qu'elles font, avant d'essayer de gagner quelques nanosecondes.


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 thread peut fonctionner sur eux. S'il y a plus d'un thread alors le second thread devra attendre que le premier finisse et le troisième devra attendre que le premier et le second finissent et ainsi de suite. Cela rend le processus très lent et donc les performances en cas de StringBuffer sont faibles.

D'autre part, 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 les performances de StringBuilder sont élevées.


La principale différence est StringBuffer est synchronisé mais StringBuilder est pas. Si vous devez utiliser plus d'un thread, StringBuffer est recommandé. Mais, selon la vitesse d'exécution StringBuilder est plus rapide que StringBuffer , car il n'est pas synchronisé.


Mieux vaut utiliser StringBuilder car il n'est pas synchronisé et donc de meilleures performances. StringBuilder est un remplacement de l'ancien StringBuffer.


Puisque StringBuffer est synchronisé, il nécessite un effort supplémentaire, donc basé sur la perforamance, c'est un peu lent que StringBuilder .


StringBuffer est utilisé pour stocker les chaînes de caractères qui seront modifiées (les objets String ne peuvent pas être modifiés). Il se développe automatiquement au besoin. Classes liées: Chaîne, CharSequence.

StringBuilder a été ajouté dans Java 5. Il est identique à tous égards à 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 monothread, le cas le plus courant, en évitant le surcroît de synchronisation, rend le StringBuilder très légèrement plus rapide.


StringBuilder a été introduit dans Java 1.5 de sorte qu'il ne fonctionnera pas avec les JVM antérieures.

Depuis les StringBuilder :

La classe StringBuilder fournit une API compatible avec StringBuffer, mais sans garantie de synchronisation. Cette classe est conçue pour être utilisée comme remplacement direct de StringBuffer aux endroits où le buffer de chaînes é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 n'est pas thread-safe. String Buffer est. Plus d'infos here .

EDIT: Pour ce qui est de la performance, après le hotspot , StringBuilder est le gagnant. Cependant, pour de petites itérations, la différence de performance est négligeable.


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

    }
}


StringBuilder est plus rapide que StringBuffer car il n'est pas synchronized .

Voici un test de référence simple:

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

Un test donne les nombres de 2241 ms pour StringBuffer vs 753 ms pour StringBuilder .


StringBuffer

  • Synchronisé d'où threadsafe
  • thread sécurisé donc lent
  • -

StringBuilder

  • Introduit en Java 5.0
  • Asynchrone donc rapide et efficace
  • L'utilisateur doit explicitement le synchroniser, s'il le souhaite
  • Vous pouvez le remplacer par StringBuilder sans autre changement

StringBuffer est synchronisé, mais StringBuilder ne l'est pas. Par conséquent, StringBuilder est plus rapide que StringBuffer .


StringBuilder et StringBuffer sont presque les mêmes. 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 un SUN. Cela évite simplement la synchronisation de toutes les méthodes publiques. Plutôt que 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 StringBuffer . Si votre texte va changer mais est utilisé par un seul thread, utilisez StringBuilder .


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-Buffer

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

Il est recommandé d'utiliser StringBuilder dans la mesure du 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

StringBuffer est mutable signifie que l'on peut changer la valeur de l'objet. L'objet créé via StringBuffer est stocké dans le tas. StringBuffer a les mêmes méthodes que StringBuilder, mais chaque méthode de StringBuffer est synchronisée, StringBuffer est thread-safe.

pour cette raison, il ne permet pas à deux threads d'accéder simultanément à la même méthode. Chaque méthode peut être accédée par un fil à la fois.

Mais être thread-safe a aussi des désavantages lorsque les performances du StringBuffer sont dues à la propriété thread safe. Ainsi, StringBuilder est plus rapide que StringBuffer lorsqu'il appelle les mêmes méthodes de chaque classe.

La valeur StringBuffer peut être modifiée, cela signifie qu'elle peut être affectée à la nouvelle valeur. De nos jours, c'est une question d'entrevue la plus commune, les différences entre les classes ci-dessus. String Buffer peut être converti en chaîne à l'aide de 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 identique à StringBuffer, c'est-à-dire qu'il stocke l'objet dans le tas et il peut également être modifié. La principale différence entre StringBuffer et StringBuilder est que StringBuilder n'est pas non plus thread-safe. StringBuilder est rapide car il n'est pas sûr pour les threads.

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: Chaîne Vs StringBuffer Vs StringBuilder


StringBuffer

StringBuffer est mutable signifie que l'on peut changer la valeur de l'objet. L'objet créé via StringBuffer est stocké dans le tas. StringBuffer a les mêmes méthodes que StringBuilder, mais chaque méthode de StringBuffer est synchronisée, StringBuffer est thread-safe.

StringBuilder

StringBuilder est identique à StringBuffer, c'est-à-dire qu'il stocke l'objet dans le tas et il peut également être modifié. La principale différence entre StringBuffer et StringBuilder est que StringBuilder n'est pas thread-safe. StringBuilder est rapide car il n'est pas sûr pour les threads.





stringbuffer