web-dev-qa-db-fra.com

Concaténer un entier dans une chaîne - utiliser un littéral ou une primitive chaîne du point de vue de la performance et de la mémoire?

Option 1:

String newStr = someStr + 3 + "]";

Option 2:

String newStr = someStr + "3" + "]";

Quelle option est la meilleure en termes de performances, de mémoire et de pratique générale? Quels sont les outils/moyens recommandés que je peux utiliser pour mesurer l'utilisation de la mémoire de mon code et ses performances (en plus de mesurer l'heure de début et l'heure de fin et de calculer la différence)

8
user1739658

Le premier deviendra:

StringBuilder sb = new StringBuilder (String.valueOf (someStr));
sb.append (3);
sb.append ("]");
String newStr = sb.toString ();

la seconde deviendra:

StringBuilder sb = new StringBuilder (String.valueOf (someStr));
sb.append ("3");
sb.append ("]");
String newStr = sb.toString ();

Voici le démontage:

public String foo (String someStr)
{
    String newStr = someStr + 3 + "]";
    return newStr;
}

public String bar (String someStr)
{
    String newStr = someStr + "3" + "]";
    return newStr;
}

public Java.lang.String foo(Java.lang.String);
Code:
   0: new           #16                 // class Java/lang/StringBuilder
   3: dup
   4: aload_1
   5: invokestatic  #18                 // Method Java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
   8: invokespecial #24                 // Method Java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
  11: iconst_3
  12: invokevirtual #27                 // Method Java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
  15: ldc           #31                 // String ]
  17: invokevirtual #33                 // Method Java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  20: invokevirtual #36                 // Method Java/lang/StringBuilder.toString:()Ljava/lang/String;
  23: astore_2
  24: aload_2
  25: areturn

public Java.lang.String bar(Java.lang.String);
Code:
   0: new           #16                 // class Java/lang/StringBuilder
   3: dup
   4: aload_1
   5: invokestatic  #18                 // Method Java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
   8: invokespecial #24                 // Method Java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
  11: ldc           #44                 // String 3
  13: invokevirtual #33                 // Method Java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  16: ldc           #31                 // String ]
  18: invokevirtual #33                 // Method Java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  21: invokevirtual #36                 // Method Java/lang/StringBuilder.toString:()Ljava/lang/String;
  24: astore_2
  25: aload_2
  26: areturn
10
Mikhail Vladimirov

Il n'y aura pas de différence notable entre les deux. Utilisez ce que vous trouvez le plus logique et lisible. j'utiliserais

String newStr = someStr + "3]";
7
JB Nizet

Je recommanderais Jprofiler comme un excellent outil de profilage d’applications Java qui m’a aidé à trouver de nombreux problèmes de mémoire.

Je ne pense pas que les options 1 et 2 aient une grande différence en termes d’utilisation de la mémoire, en particulier s’il s’agit d’une application de bureau.

3
Simon

En supposant que someString soit constant, les deux sont expressions constantes et seront évalués lors de la compilation. Ils se traduiront par des fichiers de classe et un comportement d'exécution identiques.

Source: La Spécification du langage Java écrit:

Une expression constante au moment de la compilation est une expression désignant une valeur de type primitif ou une chaîne qui ne se termine pas brutalement et qui est composée uniquement à l'aide des éléments suivants: 

  • Littéraux de type primitif et littéraux de type Chaîne (§3.10.1, §3.10.2, §3.10.3, §3.10.4, §3.10.5) 

  • Les opérateurs additifs + et - (§15.18) 

  • ...

Les expressions constantes au moment de la compilation de type String sont toujours "internées" afin de partager des instances uniques, à l'aide de la méthode String.intern. 

Si someString n'est pas une constante, la plupart des compilateurs modernes utiliseront StringBuilder, qui est explicitement autorisé par la spécification du langage Java:

Le résultat de la concaténation de chaîne est une référence à un objet String qui est la concaténation des deux chaînes d'opérande. Les caractères de l'opérande de gauche précèdent ceux de l'opérande de droite dans la chaîne nouvellement créée.

L'objet String est nouvellement créé (§12.5) sauf si l'expression est une expression constante au moment de la compilation (§15.28).

Une implémentation peut choisir d'effectuer la conversion et la concaténation en une étape pour éviter de créer puis de rejeter un objet String intermédiaire. Pour augmenter les performances de la concaténation de chaînes répétée, un compilateur Java peut utiliser la classe StringBuffer ou une technique similaire pour réduire le nombre d'objets String intermédiaires créés lors de l'évaluation d'une expression.

Pour les types primitifs, une implémentation peut également optimiser la création d'un objet wrapper en convertissant directement un type primitif en chaîne. 

2
meriton

Chaque fois que vous concaténez une chaîne, à chaque concaténation, vous créez une nouvelle copie de la chaîne et les deux chaînes sont copiées, un caractère à la fois. Il en résulte une complexité temporelle de O (n2) (McDowell).

Si vous souhaitez améliorer les performances, utilisez

StringBuilder

Un de ses constructeurs a la syntaxe suivante:

public StringBuilder(int size); //Contains no character. Initial capacity of 'size'. 

StringBuilder (séquence mutable de caractères. N'oubliez pas les chaînes sont immuables) permet de résoudre ce problème en créant simplement un tableau redimensionnable de toutes les chaînes. ne les recopier dans une chaîne que lorsque cela est nécessaire (McDowell).

StringBuilder str = new StringBuilder(0);
str.append(someStr);
str.append(3);
str.append("]");

Référence:

McDowell, Gayle Laakmann. Cracking The Coding Interview, 6ème édition. Impression.

"Constructeur de chaînes (Java Platform SE 8)". Docs.Oracle.com. N.p., 2016. Web. 4 juin 2016.

0
fonji