Ich entscheide mich immer für die zweite Methode (unter Verwendung der GString-Vorlage). Wenn jedoch mehr als ein paar Parameter wie Sie vorhanden sind, neige ich dazu, sie einzuschließen, ${X}
da ich finde, dass sie besser lesbar sind.
Das Ausführen einiger Benchmarks (unter Verwendung des hervorragenden GBench-Moduls von Nagai Masato ) für diese Methoden zeigt auch, dass das Templating schneller ist als die anderen Methoden:
@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()
Das gibt mir die folgende Ausgabe auf meinem Computer:
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
Mit Lesbarkeit und Geschwindigkeit würde ich empfehlen, Vorlagen zu erstellen ;-)
NB: Wenn Sie toString()
am Ende der GString-Methoden hinzufügen, um den Ausgabetyp mit den anderen Metriken identisch zu machen, einen faireren Test durchzuführen StringBuilder
und StringBuffer
die GString-Methoden hinsichtlich der Geschwindigkeit zu übertreffen. Da GString für die meisten Dinge anstelle von String verwendet werden kann (Sie müssen nur mit Map-Schlüsseln und SQL-Anweisungen vorsichtig sein), kann es meistens ohne diese endgültige Konvertierung belassen werden
Hinzufügen dieser Tests (wie in den Kommentaren gefragt)
'GString template toString' {
"$foo$bar$baz".toString()
}
'Readable GString template toString' {
"${foo}${bar}${baz}".toString()
}
Jetzt bekommen wir die Ergebnisse:
String adder 514
GString template 267
Readable GString template 269
GString template toString 478
Readable GString template toString 480
StringBuilder 321
StringBuffer 369
Wie Sie sehen können (wie gesagt), ist es langsamer als StringBuilder oder StringBuffer, aber immer noch etwas schneller als das Hinzufügen von Strings ...
Aber noch viel lesbarer.
Bearbeiten Sie nach Kommentar von Ruralcoder unten
Auf die neueste Gbench aktualisiert, größere Zeichenfolgen zur Verkettung und ein Test mit einem StringBuilder, der auf eine gute Größe initialisiert wurde:
@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()
gibt
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()
den beiden GString-Tests angehängten erneut ausführen. Mein Lauf zeigt, dass sie dann fast die gleiche Leistung erbringen wieString adder
. Ich vermute, dass der Test, den Sie ausgeführt haben, die Verkettung nicht wirklich handhabt, sondern lediglich ein GString-Objekt erstellt und die Referenzen speichert.StringBuilder
ist immer noch die schnellste, zweifellos, wenn SieString
irgendwann eine brauchen .GString
„wie sie ist“, an einem gewissen Punkt ist es zu einem echten umgewandelt werden mussString
, (auch nur zum Ausdrucken), so dass der wahre Zeitpunkt der letzte Satz ist. Am EndeGString
schlägt die Lesbarkeit von Vorlagen,StringBuilder
wenn das Timing so nah ist, also ist es strittig. :-)Ich bin mir nicht ganz sicher, warum die obige Antwort in Benchmarks, String-Puffer, Tests usw. gehen muss.
quelle
Reproduzieren der Antwort tim_yates auf der aktuellen Hardware und Hinzufügen der Methoden leftShift () und concat (), um den Befund zu überprüfen:
Das Ergebnis zeigt, dass concat () die schnellere Lösung für einen reinen String ist. Wenn Sie jedoch GString an einem anderen Ort verarbeiten können, liegt die GString-Vorlage noch vor Ihnen, während die Erwähnung mit leftShift () (bitweiser Operator) und StringBuffer () mit initial erfolgen sollte Zuweisung:
quelle