jeudi 29 octobre 2009

StringBuffer vs StringBuilder

La classe StringBuffer (java.lang.StringBuffer) est présente dans le JDK (Java Development Kit) depuis sa première version. Les objets de classe StringBuffer permettent de construire des chaînes de caractères avec des performances nettement supérieures à la construction des chaînes de caractères par concaténation de chaînes prémisses.

Le spécification Java SE 5 introduit la classe StringBuilder (java.lang.StringBuilder) proposant un service comparable et une interface similaire à celle de la classe StringBuffer. 

Les méthodes de la classe StringBuffer sont synchronisées tandis que celle des StringBuilder ne le sont pas. Ainsi les objets de classe StringBuilder sont sensiblement plus performant que les objets de classe StringBuffer mais ne doivent pas être modifiés de manière concurrente par différents threads.

Il reste rare qu'un StringBuffer soit modifié en parallèle dans les applications et il est conseillé d'opter pour un objet de classe StringBuilder lorsque c'est possible. Quant aux codes sources existants, la similitude des interfaces des classes StringBuffer et StringBuilder permet un remaniement du code sans douleur.

Le programme ci-dessous donne un exemple de différence des performances entre les objets de classe StringBuffer et ceux de classe StringBuilder.

public class Main {
    public static void main(String[] args) {
        Main main = new Main();
        for(int i = 0 ; i < 3 ; i++){
            System.out.print("Waiting StringBufferTechnic ... ");
            main.buildStringWithStringBufferTechnic();
            System.out.print(" : ");
            main.printChrono();

            System.out.print("Waiting StringBuilderTechnic ...");
            main.buildStringWithStringBuilderTechnic();
            System.out.print(" : ");
            main.printChrono();

            System.out.println();
        }
    }

    private static final int LOOPS = 6000000;
    private static final int A_OFFSET = (int)'A';
    private static final int MODULO = 26; // Nb caractères dans l'alphabet
    
    // Gestion du chrono
    private long time;

    private void start() {
        Runtime.getRuntime().gc();
        this.time = System.currentTimeMillis();
    }

    private void stop() {
        time = System.currentTimeMillis() - time;
    }

    public void printChrono(){
        System.out.println(time + " ms");
    }

    // Méthodes de construction de chaînes

    public String buildStringWithStringBufferTechnic(){
        start();
        StringBuffer sb = new StringBuffer();
        for(int i = 0 ; i < LOOPS ; i++){
            sb.append((char)(i%MODULO)+A_OFFSET);
        }
        String s = sb.toString();
        stop();
        return s;
    }

    public String buildStringWithStringBuilderTechnic(){
        start();
        StringBuilder sb = new StringBuilder();
        for(int i = 0 ; i < LOOPS ; i++){
            sb.append( (char)(i%MODULO)+A_OFFSET );
        }
        String s = sb.toString();
        stop();
        return s;
    }
}
Ci-dessous, un exemple d'exécution de ce programme.
Waiting StringBufferTechnic ...  : 907 ms
Waiting StringBuilderTechnic ... : 453 ms

Waiting StringBufferTechnic ...  : 812 ms
Waiting StringBuilderTechnic ... : 453 ms

Waiting StringBufferTechnic ...  : 844 ms
Waiting StringBuilderTechnic ... : 453 ms
Liens externes :

Aucun commentaire:

Enregistrer un commentaire