Existe-t-il une différence perceptible entre l'utilisation String.format
et la concaténation de chaînes en Java?
J'ai tendance à utiliser String.format
mais parfois je glisse et j'utilise une concaténation. Je me demandais si l'un était meilleur que l'autre.
La façon dont je le vois, String.format
vous donne plus de pouvoir dans le "formatage" de la chaîne; et la concaténation signifie que vous n'avez pas à vous soucier de mettre accidentellement un% s supplémentaire ou d'en manquer un.
String.format
est également plus court.
Laquelle est la plus lisible dépend du fonctionnement de votre tête.
java
string
concatenation
string.format
Omar Kooheji
la source
la source
Réponses:
Je dirais que c'est une meilleure pratique à utiliser
String.format()
. La raison principale est qu'ilString.format()
peut être plus facilement localisé avec du texte chargé à partir de fichiers de ressources alors que la concaténation ne peut pas être localisée sans produire un nouvel exécutable avec un code différent pour chaque langue.Si vous prévoyez que votre application soit localisable, vous devriez également prendre l'habitude de spécifier des positions d'argument pour vos jetons de format:
Cela peut ensuite être localisé et faire échanger les jetons de nom et d'heure sans nécessiter une recompilation de l'exécutable pour tenir compte des différents ordres. Avec les positions d'argument, vous pouvez également réutiliser le même argument sans le passer deux fois dans la fonction:
la source
À propos des performances:
Les résultats temporels sont les suivants:
Par conséquent, la concaténation est beaucoup plus rapide que String.format.
la source
javap -c StringTest.class
vous verrez que le compilateur convertit automatiquement "+" en StringBuilder uniquement si vous n'êtes pas dans une boucle. Si la concaténation est entièrement effectuée sur une seule ligne, c'est la même chose que d'utiliser '+', mais si vous utilisezmyString += "morechars";
oumyString += anotherString;
sur plusieurs lignes, vous remarquerez que plusieurs StringBuilder peuvent être créés, donc l'utilisation de "+" n'est pas toujours aussi efficace comme StringBuilder.+
ne sont pas converties enStringBuilder.append()
mais unnew StringBuilder()
se produit à chaque itération.Puisqu'il y a une discussion sur les performances, j'ai pensé que j'ajouterais une comparaison qui incluait StringBuilder. Il est en fait plus rapide que le concat et, naturellement, l'option String.format.
Pour en faire une sorte de comparaison de pommes à pommes, j'instancie un nouveau StringBuilder dans la boucle plutôt qu'à l'extérieur (c'est en fait plus rapide que de faire une seule instanciation très probablement en raison de la surcharge de réallocation d'espace pour l'ajout en boucle à la fin de un constructeur).
la source
String
. Pour être juste, le test StringBuilder a besoin d'une étape finale qui transforme le contenu de StringBuilder en une chaîne. Vous faites cela en appelantbldString.toString()
. J'éspère que ça l'explique?String s = bldString.toString();
Les synchronisations étaient avec concaténation et constructeur de cordes presque à égalité:Format = 1520 millisecond
,Concatenation = 167 millisecond
,String Builder = 173 millisecond
je les ai couru dans une boucle et moyennées chacun dehors pour obtenir un bon représentant: (optimisation pré-jvm, va essayer une boucle 10000+ quand je reçois le temps)Un problème
.format
est que vous perdez la sécurité de type statique. Vous pouvez avoir trop peu d'arguments pour votre format, et vous pouvez avoir les mauvais types pour les spécificateurs de format - les deux conduisant à uneIllegalFormatException
exécution , vous pourriez donc vous retrouver avec un code de journalisation qui interrompt la production.En revanche, les arguments de
+
peuvent être testés par le compilateur.L' histoire de la sécurité deprintf(sur laquelle la
format
fonction est modelée) est longue et effrayante.la source
Vous avez obtenu votre réponse juste là.
C'est une question de goût personnel.
La concaténation de chaînes est légèrement plus rapide, je suppose, mais cela devrait être négligeable.
la source
Voici un test avec plusieurs tailles d'échantillon en millisecondes.
}
la source
Voici le même test que ci-dessus avec la modification de l'appel de la méthode toString () sur le StringBuilder . Les résultats ci-dessous montrent que l'approche StringBuilder est juste un peu plus lente que la concaténation de chaînes en utilisant l' opérateur + .
fichier: StringTest.java
Commandes Shell: (compiler et exécuter StringTest 5 fois)
Résultats :
la source
String.format()
est plus qu'une simple concaténation de chaînes. Par exemple, vous pouvez afficher des nombres dans des paramètres régionaux spécifiques à l'aide deString.format()
.Cependant, si vous ne vous souciez pas de la localisation, il n'y a pas de différence fonctionnelle. Peut-être que l'un est plus rapide que l'autre, mais dans la plupart des cas, il sera négligeable.
la source
En règle générale, la concaténation de chaînes doit être préférée à
String.format
. Ce dernier présente deux principaux inconvénients:Par point 1, je veux dire qu'il n'est pas possible de comprendre ce que fait un
String.format()
appel en une seule passe séquentielle. On est obligé d'aller et venir entre la chaîne de format et les arguments, tout en comptant la position des arguments. Pour les concaténations courtes, ce n'est pas vraiment un problème. Dans ces cas, cependant, la concaténation de chaînes est moins détaillée.Par point 2, je veux dire que la partie importante du processus de construction est codée dans la chaîne de format (en utilisant un DSL). L'utilisation de chaînes pour représenter le code présente de nombreux inconvénients. Il n'est pas intrinsèquement sûr pour le type et complique la mise en évidence de la syntaxe, l'analyse de code, l'optimisation, etc.
Bien entendu, lors de l'utilisation d'outils ou de frameworks externes au langage Java, de nouveaux facteurs peuvent entrer en jeu.
la source
Je n'ai pas fait de benchmarks spécifiques, mais je pense que la concaténation peut être plus rapide. String.format () crée un nouveau formateur qui, à son tour, crée un nouveau StringBuilder (avec une taille de seulement 16 caractères). C'est une bonne quantité de surcharge, surtout si vous formatez une chaîne plus longue et que StringBuilder doit continuer à être redimensionné.
Cependant, la concaténation est moins utile et plus difficile à lire. Comme toujours, cela vaut la peine de faire un benchmark sur votre code pour voir lequel est le meilleur. Les différences peuvent être négligeables dans l'application serveur une fois que vos ensembles de ressources, paramètres régionaux, etc. sont chargés en mémoire et que le code est JITted.
Peut-être que comme meilleure pratique, ce serait une bonne idée de créer votre propre Formateur avec un StringBuilder (Appendable) et des Paramètres régionaux correctement dimensionnés et de les utiliser si vous avez beaucoup de mise en forme à faire.
la source
Il pourrait y avoir une différence perceptible.
String.format
est assez complexe et utilise une expression régulière en dessous, alors ne prenez pas l'habitude de l'utiliser partout, mais seulement là où vous en avez besoin.StringBuilder
serait un ordre de grandeur plus rapide (comme quelqu'un l'a déjà souligné ici).la source
Je pense que nous pouvons aller de l'avant
MessageFormat.format
car il devrait être bon à la fois en termes de lisibilité et de performances.J'ai utilisé le même programme que celui utilisé par Icaro dans sa réponse ci-dessus et je l'ai amélioré avec un code ajouté
MessageFormat
pour expliquer les performances.MISES À JOUR:
Selon le rapport SonarLint, les chaînes de format de style Printf doivent être utilisées correctement (squid: S3457)
Étant donné que les
printf-style
chaînes de format sont interprétées au moment de l'exécution plutôt que validées par le compilateur, elles peuvent contenir des erreurs entraînant la création de chaînes incorrectes. Cette règle valide statiquement la corrélation desprintf-style
chaînes de format à leurs arguments lors de l' appel au format (...) les méthodesjava.util.Formatter
,java.lang.String
,java.io.PrintStream
,MessageFormat
, et lesjava.io.PrintWriter
classes et lesprintf(...)
méthodes dejava.io.PrintStream
oujava.io.PrintWriter
classes.Je remplace le style printf par les accolades et j'ai obtenu des résultats intéressants comme ci-dessous.
Ma conclusion:
Comme je l'ai souligné ci-dessus, l'utilisation de String.format avec des accolades devrait être un bon choix pour obtenir des avantages de bonne lisibilité et de performances.
la source
Vous ne pouvez pas comparer la concaténation de chaînes et String.Format par le programme ci-dessus.
Vous pouvez également essayer de changer la position d'utilisation de votre String.Format et Concatenation dans votre bloc de code comme ci-dessous
Vous serez surpris de voir que le format fonctionne plus rapidement ici. En effet, les objets initiaux créés peuvent ne pas être libérés et il peut y avoir un problème d'allocation de mémoire et donc de performances.
la source
Il faut un peu de temps pour s'habituer à String.Format, mais cela en vaut la peine dans la plupart des cas. Dans le monde de NRA (ne jamais répéter quoi que ce soit), il est extrêmement utile de conserver vos messages à jetons (journalisation ou utilisateur) dans une bibliothèque constante (je préfère ce qui équivaut à une classe statique) et de les appeler si nécessaire avec String.Format, que vous localisent ou non. Essayer d'utiliser une telle bibliothèque avec une méthode de concaténation est plus difficile à lire, à dépanner, à relire et à gérer avec toute approche nécessitant une concaténation. Le remplacement est une option, mais je doute qu'il soit performant. Après des années d'utilisation, mon plus gros problème avec String.Format est que la longueur de l'appel est trop longue lorsque je le passe dans une autre fonction (comme Msg), mais il est facile de se déplacer avec une fonction personnalisée pour servir d'alias .
la source