StringBuffer contre String

Java fournit les classes StringBufferet String, et la Stringclasse est utilisée pour manipuler les chaînes de caractères qui ne peuvent pas être modifiées. En termes simples, les objets de type Stringsont en lecture seule et immuables. La StringBufferclasse est utilisée pour représenter des caractères qui peuvent être modifiés.

La différence de performances significative entre ces deux classes est qu'elle StringBufferest plus rapide que Stringlors de l'exécution de concaténations simples. Dans le Stringcode de manipulation, les chaînes de caractères sont régulièrement concaténées. En utilisant la Stringclasse, les concaténations sont généralement effectuées comme suit:

String str = nouvelle chaîne ("Stanford"); str + = "Perdu !!";

Si vous deviez utiliser StringBufferpour effectuer la même concaténation, vous auriez besoin d'un code qui ressemble à ceci:

StringBuffer str = nouveau StringBuffer ("Stanford"); str.append ("Perdu !!");

Les développeurs supposent généralement que le premier exemple ci-dessus est plus efficace car ils pensent que le deuxième exemple, qui utilise la appendméthode de concaténation, est plus coûteux que le premier exemple, qui utilise l' +opérateur pour concaténer deux Stringobjets.

L' +opérateur semble innocent, mais le code généré produit quelques surprises. L'utilisation d'une StringBufferconcaténation for peut en fait produire du code beaucoup plus rapide que l'utilisation d'un fichier String. Pour découvrir pourquoi c'est le cas, nous devons examiner le bytecode généré à partir de nos deux exemples. Le bytecode de l'exemple utilisant Stringressemble à ceci:

0 nouveau # 7 3 dup 4 ldc # 2 6 invokespecial # 12 9 astore_1 10 nouveau # 8 13 dup 14 aload_1 15 invokestatic # 23 18 invokespecial # 13 21 ldc # 1 23 invokevirtual # 15 26 invokevirtual # 22 29 astore_1 

Le bytecode aux emplacements 0 à 9 est exécuté pour la première ligne de code, à savoir:

 String str = nouvelle chaîne ("Stanford"); 

Ensuite, le bytecode aux emplacements 10 à 29 est exécuté pour la concaténation:

 str + = "Perdu !!"; 

Les choses deviennent intéressantes ici. Le bytecode généré pour la concaténation crée un StringBufferobjet, puis appelle sa appendméthode: l' StringBufferobjet temporaire est créé à l'emplacement 10, et sa appendméthode est appelée à l'emplacement 23. La Stringclasse étant immuable, a StringBufferdoit être utilisé pour la concaténation.

Une fois la concaténation effectuée sur l' StringBufferobjet, il doit être reconverti en fichier String. Cela se fait avec l'appel à la toStringméthode à l'emplacement 26. Cette méthode crée un nouvel Stringobjet à partir de l' StringBufferobjet temporaire . La création de cet StringBufferobjet temporaire et sa conversion ultérieure en Stringobjet sont très coûteuses.

En résumé, les deux lignes de code ci-dessus aboutissent à la création de trois objets:

  1. Un Stringobjet à l'emplacement 0
  2. Un StringBufferobjet à l'emplacement 10
  3. Un Stringobjet à l'emplacement 26

Maintenant, regardons le bytecode généré pour l'exemple en utilisant StringBuffer:

0 nouveau # 8 3 dup 4 ldc # 2 6 invokespecial # 13 9 astore_1 10 aload_1 11 ldc # 1 13 invokevirtual # 15 16 pop 

Le bytecode aux emplacements 0 à 9 est exécuté pour la première ligne de code:

 StringBuffer str = nouveau StringBuffer ("Stanford"); 

Le bytecode aux emplacements 10 à 16 est ensuite exécuté pour la concaténation:

 str.append ("Perdu !!"); 

Notez que, comme c'est le cas dans le premier exemple, ce code appelle la appendméthode d'un StringBufferobjet. Contrairement au premier exemple, cependant, il n'est pas nécessaire de créer un temporaire StringBuffer, puis de le convertir en Stringobjet. Ce code crée un seul objet, le StringBuffer, à l'emplacement 0.

En conclusion, la StringBufferconcaténation est nettement plus rapide que la Stringconcaténation. Évidemment, les StringBuffers doivent être utilisés dans ce type d'opération lorsque cela est possible. Si la fonctionnalité de la Stringclasse est souhaitée, envisagez d'utiliser un StringBufferpour la concaténation, puis d'effectuer une conversion en String.

Reggie Hutcherson est un évangéliste de la technologie Sun. Il évangélise les technologies de la plate-forme Java 2 de Sun dans le monde entier en se concentrant sur J2SE et le moteur de performance HotSpot.

En savoir plus sur ce sujet

  • « JavaWorld lance une nouvelle chronique hebdomadaire sur les performances Java», Reggie Hutcherson ( JavaWorld, mars 2000)

    //www.javaworld.com/jw-03-2000/jw-03-javaperf.html

  • «Les bases des performances Java», Reggie Hutcherson ( JavaWorld, mars 2000)

    //www.javaworld.com/jw-03-2000/jw-03-javaperf_2.html

  • "Problème de performance ou problème de conception?" Reggie Hutcherson ( JavaWorld, mars 2000)

    //www.javaworld.com/jw-03-2000/jw-03-javaperf_3.html

  • «Optimisations du compilateur», Reggie Hutcherson ( JavaWorld, mars 2000)

    //www.javaworld.com/jw-03-2000/jw-03-javaperf_4.html

Cette histoire, "StringBuffer versus String" a été initialement publiée par JavaWorld.