Vado sempre per il secondo metodo (usando il modello GString), anche se quando ci sono più di un paio di parametri come te, tendo a includerli ${X}
perché trovo che lo renda più leggibile.
L'esecuzione di alcuni benchmark (utilizzando l' eccellente modulo GBench di Nagai Masato ) su questi metodi mostra anche che il templating è più veloce degli altri metodi:
@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()
Questo mi dà il seguente output sulla mia macchina:
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
Quindi, con la leggibilità e la velocità a suo favore, consiglierei di creare modelli ;-)
NB: se aggiungi toString()
alla fine dei metodi GString per rendere il tipo di output uguale alle altre metriche e renderlo un test più equo, StringBuilder
eStringBuffer
rendilo batti i metodi GString per la velocità. Tuttavia, poiché GString può essere utilizzato al posto di String per la maggior parte delle cose (devi solo prestare attenzione con le chiavi Map e le istruzioni SQL), può essere lasciato senza questa conversione finale
Aggiungendo questi test (come è stato chiesto nei commenti)
'GString template toString' {
"$foo$bar$baz".toString()
}
'Readable GString template toString' {
"${foo}${bar}${baz}".toString()
}
Ora otteniamo i risultati:
String adder 514
GString template 267
Readable GString template 269
GString template toString 478
Readable GString template toString 480
StringBuilder 321
StringBuffer 369
Quindi, come puoi vedere (come ho detto), è più lento di StringBuilder o StringBuffer, ma comunque un po 'più veloce dell'aggiunta di stringhe ...
Ma ancora molto più leggibile.
Modifica dopo il commento di ruralcoder di seguito
Aggiornato all'ultimo gbench, stringhe più grandi per la concatenazione e un test con uno StringBuilder inizializzato a una buona dimensione:
@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()
dà
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()
aggiunta dei due test GString. La mia corsa mostra che poi si comportano quasi allo stesso modo diString adder
. La mia ipotesi è che il test che hai eseguito in realtà non gestisca la concatenazione, quindi si limita a creare un oggetto GString e memorizzare i riferimenti.StringBuilder
è ancora il più veloce, senza dubbio, se ad unString
certo punto ne hai bisogno .