Pour concaténer String
nous utilisons souvent StringBuilder
au lieu de String
+ String
, mais nous pouvons également faire de même avec String.format
qui retourne la chaîne formatée selon les paramètres régionaux, le format et les arguments donnés.
Exemples:
Concaténer la chaîne avec StringBuilder
String concatenateStringWithStringBuilder(String name, String lName, String nick) {
final StringBuilder sb = new StringBuilder("Contact {");
sb.append(", name='").append(name)
.append(", lastName='").append(lName)
.append(", nickName='").append(nick)
.append('}');
return sb.toString();
}
Concaténer la chaîne avec StringFormat:
String concatenateStringWithStringFormat(String name, String lName, String nick) {
return String.format("Contact {name=%s, lastName=%s, nickName=%s}", name, lName, nick);
}
En termes de performances, est String.Format
aussi efficace que StringBuilder
? Lequel est préférable de concaténer des chaînes et pourquoi?
[~ # ~] mise à jour [~ # ~]
J'ai vérifié le même question , mais ne répond pas à ma question. Jusqu'à présent, j'ai utilisé StringBuilder
pour concaténer des chaînes, dois-je le suivre en utilisant? Ou dois-je utiliser String.format
? la question est laquelle est la meilleure et pourquoi?
Après avoir fait un petit test avec StringBuilder
vs String.format
J'ai compris combien de temps il faut à chacun pour résoudre la concaténation. Voici le code d'extrait et les résultats
Code:
String name = "stackover";
String lName = " flow";
String nick = " stackoverflow";
String email = "[email protected]";
int phone = 123123123;
//for (int i = 0; i < 10; i++) {
long initialTime1 = System.currentTimeMillis();
String response = String.format(" - Contact {name=%s, lastName=%s, nickName=%s, email=%s, phone=%d}",
name, lName, nick, email, phone);
long finalTime1 = System.currentTimeMillis();
long totalTime1 = finalTime1 - initialTime1;
System.out.println(totalTime1 + response);
long initialTime2 = System.currentTimeMillis();
final StringBuilder sb = new StringBuilder(" - Contact {");
sb.append("name=").append(name)
.append(", lastName=").append(lName)
.append(", nickName=").append(nick)
.append(", email=").append(email)
.append(", phone=").append(phone)
.append('}');
String response2 = sb.toString();
long finalTime2 = System.currentTimeMillis();
long totalTime2 = finalTime2 - initialTime2;
System.out.println(totalTime2 + response2);
//}
Après avoir exécuté le code plusieurs fois, j'ai vu que String.format
prend plus de temps:
String.format: 46: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
StringBuilder: 0: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
String.format: 38: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
StringBuilder: 0: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
String.format: 51: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
StringBuilder: 0: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
Mais si je lance le même code dans une boucle, le résultat change.
String.format: 43: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
StringBuilder: 0: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
String.format: 1: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
StringBuilder: 0: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
String.format: 1: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
StringBuilder: 0: Contact {name=stackover, lastName= flow, nickName= stackoverflow, [email protected], phone=123123123}
La première fois String.format
s'exécute, cela prend plus de temps, après quoi le temps est plus court même s'il ne devient pas constant en raison de StringBuilder
Comme l'a dit @ G.Fiedler: "String.format
doit analyser la chaîne de format ... "
Avec ces résultats, on peut dire que StringBuilder
est plus efficace queString.format
Ce qui est "mieux" dépend uniquement de vos besoins:
Par exemple, String Builder
Sera plus rapide, mais le code sera beaucoup plus illisible et il serait plus facile de faire une erreur.
D'autre part, String.format()
produit un code plus lisible au détriment des performances.
Benchmark JMH pour illustrer la différence de performance (notez que le code du générateur de chaîne est plus long et très difficile à comprendre à quoi ressemblerait la chaîne résultante):
@Fork(1)
@State(Scope.Benchmark)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@Measurement(iterations = 10)
@Warmup(iterations = 10)
@BenchmarkMode(Mode.Throughput)
public class StringFormatBenchmark {
private String name = "UserName";
private String lName = "LUserName";
private String nick = "UserNick";
@Benchmark
public void stringFormat(Blackhole blackhole) {
final String result = String.format("Contact {name=%s, lastName=%s, nickName=%s}", name, lName, nick);
blackhole.consume(result);
}
@Benchmark
public void stringBuilder(Blackhole blackhole) {
final StringBuffer sb = new StringBuffer("Contact {");
sb.append(", name='").append(name)
.append(", lastName='").append(lName)
.append(", nickName='").append(nick)
.append('}');
final String result = sb.toString();
blackhole.consume(result);
}
}
Et les résultats:
Benchmark Mode Cnt Score Error Units
StringFormatBenchmark.stringBuilder thrpt 10 10617.210 ± 157.302 ops/ms
StringFormatBenchmark.stringFormat thrpt 10 960.658 ± 7.398 ops/ms
Pour le code non critique pour les performances, je préfère utiliser la fonction String.format()
, car elle est plus facile et plus agréable à utiliser. Il est également visible à quoi ressemblerait la chaîne résultante, en regardant simplement le motif. Si je fais un code de performance critique, ou quelque chose qui doit avoir un faible impact GC, j'utiliserais un StringBuilder
parce qu'il est plus rapide et peut être réutilisé.
StringBuilder
est plus rapide, car String.format
doit analyser la chaîne de format (une langue spécifique au domaine complexe). Et c'est cher.
StringBuilder au lieu de String + String
BTW: C'est la même chose, car il en résulte le même code d'octet (depuis Java 1.5).