Je choisis toujours la deuxième méthode (en utilisant le modèle GString), bien que quand il y a plus de quelques paramètres comme vous, j'ai tendance à les envelopper ${X}
car je trouve que cela le rend plus lisible.
L'exécution de quelques benchmarks (en utilisant l' excellent module GBench de Nagai Masato ) sur ces méthodes montre également que la création de modèles est plus rapide que les autres méthodes:
@Grab( 'com.googlecode.gbench:gbench:0.3.0-groovy-2.0' )
import gbench.*
def (foo,bar,baz) = [ 'foo', 'bar', 'baz' ]
new BenchmarkBuilder().run( measureCpuTime:false ) {
// Just add the strings
'String adder' {
foo + bar + baz
}
// Templating
'GString template' {
"$foo$bar$baz"
}
// I find this more readable
'Readable GString template' {
"${foo}${bar}${baz}"
}
// StringBuilder
'StringBuilder' {
new StringBuilder().append( foo )
.append( bar )
.append( baz )
.toString()
}
'StringBuffer' {
new StringBuffer().append( foo )
.append( bar )
.append( baz )
.toString()
}
}.prettyPrint()
Cela me donne la sortie suivante sur ma machine:
Environment
===========
* Groovy: 2.0.0
* JVM: Java HotSpot(TM) 64-Bit Server VM (20.6-b01-415, Apple Inc.)
* JRE: 1.6.0_31
* Total Memory: 81.0625 MB
* Maximum Memory: 123.9375 MB
* OS: Mac OS X (10.6.8, x86_64)
Options
=======
* Warm Up: Auto
* CPU Time Measurement: Off
String adder 539
GString template 245
Readable GString template 244
StringBuilder 318
StringBuffer 370
Donc, avec la lisibilité et la vitesse en sa faveur, je recommanderais la création de modèles ;-)
NB: Si vous ajoutez toString()
à la fin des méthodes GString pour rendre le type de sortie le même que les autres métriques, et en faire un test plus juste, StringBuilder
et StringBuffer
battez les méthodes GString pour la vitesse. Cependant, comme GString peut être utilisé à la place de String pour la plupart des choses (vous devez juste faire preuve de prudence avec les clés Map et les instructions SQL), il peut généralement être laissé sans cette conversion finale
Ajout de ces tests (comme cela a été demandé dans les commentaires)
'GString template toString' {
"$foo$bar$baz".toString()
}
'Readable GString template toString' {
"${foo}${bar}${baz}".toString()
}
Maintenant, nous obtenons les résultats:
String adder 514
GString template 267
Readable GString template 269
GString template toString 478
Readable GString template toString 480
StringBuilder 321
StringBuffer 369
Donc, comme vous pouvez le voir (comme je l'ai dit), c'est plus lent que StringBuilder ou StringBuffer, mais toujours un peu plus rapide que d'ajouter des chaînes ...
Mais encore beaucoup plus lisible.
Modifier après le commentaire de ruralcoder ci-dessous
Mise à jour vers le dernier gbench, des chaînes plus grandes pour la concaténation et un test avec un StringBuilder initialisé à une bonne taille:
@Grab( 'org.gperfutils:gbench:0.4.2-groovy-2.1' )
def (foo,bar,baz) = [ 'foo' * 50, 'bar' * 50, 'baz' * 50 ]
benchmark {
// Just add the strings
'String adder' {
foo + bar + baz
}
// Templating
'GString template' {
"$foo$bar$baz"
}
// I find this more readable
'Readable GString template' {
"${foo}${bar}${baz}"
}
'GString template toString' {
"$foo$bar$baz".toString()
}
'Readable GString template toString' {
"${foo}${bar}${baz}".toString()
}
// StringBuilder
'StringBuilder' {
new StringBuilder().append( foo )
.append( bar )
.append( baz )
.toString()
}
'StringBuffer' {
new StringBuffer().append( foo )
.append( bar )
.append( baz )
.toString()
}
'StringBuffer with Allocation' {
new StringBuffer( 512 ).append( foo )
.append( bar )
.append( baz )
.toString()
}
}.prettyPrint()
donne
Environment
===========
* Groovy: 2.1.6
* JVM: Java HotSpot(TM) 64-Bit Server VM (23.21-b01, Oracle Corporation)
* JRE: 1.7.0_21
* Total Memory: 467.375 MB
* Maximum Memory: 1077.375 MB
* OS: Mac OS X (10.8.4, x86_64)
Options
=======
* Warm Up: Auto (- 60 sec)
* CPU Time Measurement: On
user system cpu real
String adder 630 0 630 647
GString template 29 0 29 31
Readable GString template 32 0 32 33
GString template toString 429 0 429 443
Readable GString template toString 428 1 429 441
StringBuilder 383 1 384 396
StringBuffer 395 1 396 409
StringBuffer with Allocation 277 0 277 286
.toString()
en ajoutant aux deux tests GString. Ma course montre qu'ils exécutent alors presque la même chose queString adder
. Je suppose que le test que vous avez exécuté ne gère pas réellement la concaténation, il s'agit donc simplement de créer un objet GString et de stocker les références.StringBuilder
est toujours le plus rapide, haut la main, si vous en avez besoinString
à un moment donné.GString
"tel quel ", à un moment donné il doit être converti en un vraiString
, (même juste pour l'imprimer), donc le vrai timing est le dernier ensemble. En fin de compte, la lisibilité desGString
modèles batStringBuilder
lorsque le timing est si proche, donc c'est sans objet. :-)Je ne sais pas trop pourquoi la réponse ci-dessus doit aller dans les benchmarks, les tampons de chaînes, les tests, etc.
la source
Reproduction de la réponse tim_yates sur le matériel actuel et ajout des méthodes leftShift () et concat () pour vérifier la conclusion:
Le résultat montre que concat () est la solution la plus rapide pour une chaîne pure, mais si vous pouvez gérer GString ailleurs, le modèle GString est toujours en avance, tandis que la mention honorable doit aller à leftShift () (opérateur au niveau du bit) et StringBuffer () avec l'initiale allocation:
la source