2010-12-01 6 views
9

J'ai lu le code produit par d'autres développeurs sur mon équipe, ils semblent favoriser l'utilisation += pour la concaténation String, alors que je préfère utiliser .concat() comme il se sent plus facile à lire. J'essaie de préparer un argument pour expliquer pourquoi il est préférable d'utiliser .concat(), et je me demande s'il y a une différence d'efficacité entre les deux?Est + = plus efficace que concat?

Quelle option "devrait" nous prendre?

public class Stuff { 

    public static void main(String[] args) { 

     String hello = "hello "; 
     hello += "world"; 
     System.out.println(hello); 

     String helloConcat = "hello ".concat("world"); 
     System.out.println(helloConcat); 
    } 
} 
+2

vérifier cela http://stackoverflow.com/questions/47605/java-string-concatenation –

Répondre

6

Comme chaîne est immuable en Java, lorsque vous faites une +, += ou concat(String), une nouvelle chaîne est générée . Plus la chaîne est longue, plus il faut de temps - il y a plus à copier et plus de déchets sont produits.

compilateurs java Aujourd'hui, optimise votre concaténation de chaîne pour la rendre optimale, par exemple

System.out.println("x:"+x+" y:"+y); 

compilateur génère à:

System.out.println((new StringBuilder()).append("x:").append(x).append(" y:").append(y).toString()); 

Mon conseil est d'écrire du code qui est plus facile à maintenir et à lire.

Ce lien montre la performance de StringBuilder vs StringBuffer vs String.concat - done right

10

Cela ne devrait pas avoir d'importance. Les compilateurs Java modernes, les JVM et les JIT optimisent votre code de sorte que les différences soient minimes. Vous devriez vous efforcer d'écrire du code plus lisible et plus facile à gérer pour vous.

+0

Que diriez-vous dans le cas de processeurs mobiles ou où les ressources sont faibles, encore ces minimal n'aurait pas d'importance? – Pratik

+0

@Pratik: ce sont des cas où l'optimisation est importante. La question de l'OP n'indiquait pas que des micro-optimisations étaient nécessaires. Bien sûr, vous devez faire attention à ce que vous faites en fonction de votre environnement. Si vous vouliez écrire un système d'exploitation, vous ne le feriez pas dans un langage dynamique lent si vous voulez qu'il soit très rapide. – darioo

+0

Je ne suis pas sûr de l'optimisation que vous envisagez ici. –

5

Je suis d'accord avec @darioo et la plupart des autres réponses. Toujours mettre la lisibilité (et la maintenabilité) en premier. (Un compilateur JIT moderne ne devrait pas avoir des problèmes avec des cas simples comme ceux-ci.)

Voici cependant le bytecode correspondant à votre programme. (Notez que les += approche aboutit à une StringBuilder qui est généralement l'approche privilégiée lors de la construction des chaînes.)

// String hello = "hello"; 
0: ldC#2; //String hello 
2: astore_1 

// hello += "world"; 
3: new #3; //class java/lang/StringBuilder 
6: dup 
7: invokespecial #4; //Method StringBuilder."<init>" 
10: aload_1 
11: invokevirtual #5; //Method StringBuilder.append 
14: ldC#6; //String world 
16: invokevirtual #5; //Method StringBuilder.append 
19: invokevirtual #7; //Method StringBuilder.toString 

// System.out.println(hello); 
22: astore_1 
23: getstatiC#8; //Field System.out 
26: aload_1 
27: invokevirtual #9; //Method PrintStream.println 

// String helloConcat = "hello ".concat("world"); 
30: ldC#2; //String hello 
32: ldC#6; //String world 
34: invokevirtual #10; //Method String.concat 
37: astore_2 

// System.out.println(helloConcat); 
38: getstatiC#8; //Field System.out 
41: aload_2 
42: invokevirtual #9; //Method PrintStream.println 

45: return 
3

En termes de lisibilité, je pense que vous êtes très mal. + gagne plus de .concat(). Si vous utilisez +=, vous pouvez penser à StringBuilder.append en gardant le même StringBuilder pour la boucle. En termes de performance, concat est meilleure que +. tant que vous en utilisez seulement un ou peut-être deux. Dans le cas de concat, vous allez créer un objet String avec une taille correcte char[]. C'est à peu près aussi optimal que possible. Javac génère un code qui construit StringBuilder pour effectuer l'ajout, puis le convertit en String. À partir de 1.5 vous créez:

  • A StringBuilder (déchets)
  • initiale char[] pour StringBuilder (déchets)
  • Si la séquence résultant est trop long, un deuxième plus char[] (déchets)
  • Le résultat String.
  • Le d » char[]String.

Cependant, vous voyez rarement concat utilisé car il est plus difficile à lire. La performance va certainement être une goutte dans l'océan par rapport à ce qu'il se passe (indice: essayez le dos d'une enveloppe avant d'optimiser).

1

Vous devez faire ce que vous trouvez est la plus courte et la plus claire pour vous.

Cependant, pour votre intérêt. Il est le plus rapide que la compilation a combiné les deux chaînes en une seule.

C'est la plus rapide pour deux chaînes car il évite la création StringBuilder. Toutefois, si vous avez plus de deux chaînes, utilisez StringBuilder, implicitement ou explicitement, c'est le plus rapide.

En résumé, j'utiliser + sauf si vous avez dans une boucle dans ce cas, je pourrais utiliser StringBuilder explicitement pour améliorer les performances.

0

J'ai trouvé ce artical et fait ce test:

public static void main(String[] args) { 
     String s1 = generateString(); 
     String s2 = generateString(); 
     String s3 = generateString(); 
     String s4 = generateString(); 
     String s5 = generateString(); 
     String s6 = generateString(); 

     long e = System.currentTimeMillis(); 
     for(int i=0;i<10000000;i++){ 
     //StringBuilder > concat> plus >StringBuffer >plusEqual(">"means faster than) 
      //concatPlus(s1 , s2 , s3 , s4 , s5 , s6);//4204ms 
      //concatBuilder(s1 , s2 , s3 , s4 , s5 , s6);//2562ms 
      //concatBuffer(s1 , s2 , s3 , s4 , s5 , s6);//4610ms 
      //concatPlusEqual(s1 , s2 , s3 , s4 , s5 , s6);//9843ms 
      //concatConcat(s1 , s2 , s3 , s4 , s5 , s6);//3036ms 
     } 
     System.out.println(System.currentTimeMillis()-e);   
    } 

public static String concatPlusEqual(String s1, String s2, String s3, String s4, 
     String s5, String s6) { 
     String result = ""; 
     result += s1; 
     result += s2; 
     result += s3; 
     result += s4; 
     result += s5; 
     result += s6; 
     return result; 
} 

    public static String concatConcat(String s1, String s2, String s3, String s4, 
      String s5, String s6) { 
     String result = new String(); 
     result.concat(s1); 
     result.concat(s2); 
     result.concat(s3); 
     result.concat(s4); 
     result.concat(s5); 
     result.concat(s6); 
     return result; 
    } 


    public static String concatBuffer(String s1, String s2, String s3, String s4, 
      String s5, String s6) { 
     return new StringBuffer(s1.length() + s2.length() + s3.length() 
       + s4.length() + s5.length() + s6.length()).append(s1) 
       .append(s2).append(s3).append(s4).append(s5).append(s6) 
       .toString(); 
    } 

    public static String concatBuilder(String s1, String s2, String s3, String s4, 
      String s5, String s6) { 
     return new StringBuilder(s1.length() + s2.length() + s3.length() 
       + s4.length() + s5.length() + s6.length()).append(s1) 
       .append(s2).append(s3).append(s4).append(s5).append(s6) 
       .toString(); 
    } 

    public static String concatPlus(String s1,String s2,String s3,String s4,String s5,String s6) { 
     return s1 + s2 + s3 + s4 + s5 + s6; 
    } 
public static String generateString() 
    { 
     Random rng = new Random(); 
     int length = 10; 
     String characters ="ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
     char[] text = new char[length]; 
     for (int i = 0; i < length; i++) 
     { 
      text[i] = characters.charAt(rng.nextInt(characters.length())); 
     } 
     return new String(text); 
    } 

On dirait que StringBuilder est le plus rapide et += est plus lent. Juste pour référence!

1

Concat est certainement un choix plus rapide pour deux chaînes concaténation, je ne sais pas pourquoi javac utilise en interne

(new StringBuilder(String.valueOf(s1))).append(s2).toString() 

au lieu de

s1.concat(s2) 

s1 + = s2. Voir ma réponse à une question similaire concatenation operator (+) vs concat()

Questions connexes