Peut-être que je coupe les cheveux, mais je me demandais dans le cas suivant:
String newString = a + b + c; //case 1
String newString = a.concat(b).concat(c); //case 2
StringBuilder newString = new StringBuilder(); //case 3
newString.append(a);
newString.append(b);
newString.append(c);
Quel est le meilleur à utiliser?
Mieux je veux dire dans de toute façon .
En lisant ces articles, d’autres publications disent que le cas 3 n’est pas celui d’une performance optimale, d’autres que le cas 1 se retrouvera dans le cas 3, etc.
Pour être plus précis.
Par exemple, en mettant tout de côté, quel style est le plus approprié pour le voir d'un autre programmeur si vous deviez maintenir son code?
Ou que considérez-vous comme plus efficace en programmation?
Ou vous penseriez que c'est plus rapide, etc.
Je ne sais pas comment exprimer cela autrement.
Une réponse comme par exemple le cas 3 peut être plus rapide mais la grande majorité des programmeurs préfèrent le cas 1 car il est plus lisible est également accepté s'il est en quelque sorte bien élaboré
Le cas 1 est concis, exprime clairement l’intention et équivaut au cas 3.
Le cas 2 est moins efficace et également moins lisible.
Le cas 3 est presque aussi efficace que le cas 1, mais plus long et moins lisible.
L'utilisation du cas 3 n'est préférable que lorsque vous devez concaténer une boucle. Sinon, le compilateur compile les cas 1 à 3 (sauf qu'il construit le StringBuilder avec new StringBuilder(a)
), ce qui le rend encore plus efficace que votre cas 3).
Le cas 3 est la forme la plus performante, mais la machine virtuelle Java convertit le cas 1 en cas 3.
Mais je crois que le cas 2 est le pire, il n’est pas aussi lisible que le cas 1 et n’est pas aussi performant que le cas 3.
Si vous voulez concaténer une chaîne dans une boucle, utilisez le cas 3, vous pouvez tester facilement le gain de performance, mais si ce n'est pas dans une boucle (ou si vous n'ajoutez pas beaucoup de chaînes dans une séquence), elles sont presque identiques.
Les cas pour lesquels vous ne devez pas utiliser l'opérateur + sont:
String a = "";
for (String x : theStrings) {
a += x;
}
ou
String a = b + c;
a = a + d;
a = a + e;
a = a + f;
Le cas 3 est meilleur dans la plupart des aspects. Dans le cas 3, vous ne créez pas 3 objets chaîne. En raison de l'immuabilité des chaînes, 2 aura la surcharge de créer un objet chaîne pour chaque concatuit + (ou).
EDIT: Relire le document et accepter la plupart des commentaires, le cas 1 est le cas3.
Pour les cas simples, utiliser +
est clairement plus lisible.
StringBuilder
a du sens. Si vous divisez plusieurs lignes, alors +
peut rapidement nuire aux performances. Les boucles vont de O(n) performances à O (n ^ 2) - pas un problème si n est petit, mais un gros problème si n peut être grand dans des circonstances difficiles (peut-être lorsque vous faites quelque chose de critique, ou quand quelqu'un est méchant).
Contrairement aux autres réponses, si vous n'avez que trois chaînes, concat
peut être le gagnant de la performance. Suis-je mental? Non. Considérez les deux autres options. Vous créez un objet StringBuilder
name__, avec un tableau. L'ajout des chaînes peut nécessiter le remplacement du tableau et il peut rester des bits impairs à la fin du tableau (le degré de fréité d'une certaine granularité à l'attribution, donc quelques char
name__s supplémentaires peuvent augmenter ou non l'utilisation de la mémoire). Vous pouvez calculer la capacité nécessaire si vous détestez tout le monde qui lit votre code. Le meilleur des cas, deux tableaux (un pour StringBuilder
name__, un pour String
(pas de partage pour les huit dernières années)) de la taille du texte de résultat et deux autres objets (StringBuilder
et String
name__). Maintenant, pour le concat
name__, vous allez allouer des objets String
avec deux tableaux, mais le premier tableau sera c.length()
plus court. C'est une victoire! Eh bien, pas pour la lisibilité.
Clause de non-responsabilité: la machine virtuelle Java peut procéder à une optimisation sauvage, y compris à une allocation de pile après une analyse d'échappement et à une mise en boîtier spéciale des classes principales. Ils sont plus susceptibles d’optimiser du code commun et simple que du code masqué à la main.
Sur l'analyse des performances avec JDK 1.8, j'ai trouvé le cas 2 comme gagnant en termes de performances.
class Solution {
public static void main(String[] args) {
String s ="ABC", s1 = "", s2 = "", s3 = "";
long t1 = System.nanoTime();
for(int i = 1; i < 11; i++) {
s1 = s1 + s;
}
System.out.println(System.nanoTime() - t1);
System.out.println(s1);
long t2 = System.nanoTime();
for(int i = 1; i < 11; i++) {
s2 = s2.concat(s);
}
System.out.println(System.nanoTime() - t2);
System.out.println(s2);
long t3 = System.nanoTime();
StringBuilder sb = new StringBuilder();
for(int i = 1; i < 11; i++) {
sb.append(s);
}
s3 = sb.toString();
System.out.println(System.nanoTime() - t3);
System.out.println(s3);
}
}
Résultats :
40615
ABCABCABCABCABCABCABCABCABCABC
9157
ABCABCABCABCABCABCABCABCABCABC
20243
ABCABCABCABCABCABCABCABCABCABC