Я всегда выбираю второй метод (с использованием шаблона GString), хотя, когда параметров больше, чем у вас, я стараюсь обернуть их, ${X}
поскольку считаю, что это делает его более читаемым.
Выполнение некоторых тестов (с использованием превосходного модуля GBench Nagai Masato ) по этим методам также показывает, что создание шаблонов работает быстрее, чем другие методы:
@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 ) {
'String adder' {
foo + bar + baz
}
'GString template' {
"$foo$bar$baz"
}
'Readable GString template' {
"${foo}${bar}${baz}"
}
'StringBuilder' {
new StringBuilder().append( foo )
.append( bar )
.append( baz )
.toString()
}
'StringBuffer' {
new StringBuffer().append( foo )
.append( bar )
.append( baz )
.toString()
}
}.prettyPrint()
Это дает мне следующий результат на моей машине:
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
Так что, учитывая удобочитаемость и скорость, я бы рекомендовал использовать шаблоны ;-)
NB: если вы добавите toString()
в конец методов GString, чтобы тип вывода был таким же, как и другие метрики, и сделал его более справедливым тестом, StringBuilder
иStringBuffer
превзойти методы GString по скорости. Однако, поскольку GString может использоваться вместо String для большинства вещей (вам просто нужно проявлять осторожность с ключами карты и операторами SQL), его в большинстве случаев можно оставить без этого окончательного преобразования.
Добавление этих тестов (как было предложено в комментариях)
'GString template toString' {
"$foo$bar$baz".toString()
}
'Readable GString template toString' {
"${foo}${bar}${baz}".toString()
}
Теперь получаем результат:
String adder 514
GString template 267
Readable GString template 269
GString template toString 478
Readable GString template toString 480
StringBuilder 321
StringBuffer 369
Итак, как вы можете видеть (как я уже сказал), он медленнее, чем StringBuilder или StringBuffer, но все же немного быстрее, чем добавление строк ...
Но все же намного читабельнее.
Редактировать после комментария сельского кодера ниже
Обновлено до последней версии gbench, большие строки для конкатенации и тест с StringBuilder, инициализированным до подходящего размера:
@Grab( 'org.gperfutils:gbench:0.4.2-groovy-2.1' )
def (foo,bar,baz) = [ 'foo' * 50, 'bar' * 50, 'baz' * 50 ]
benchmark {
'String adder' {
foo + bar + baz
}
'GString template' {
"$foo$bar$baz"
}
'Readable GString template' {
"${foo}${bar}${baz}"
}
'GString template toString' {
"$foo$bar$baz".toString()
}
'Readable GString template toString' {
"${foo}${bar}${baz}".toString()
}
'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()
дает
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()
добавив к ним два теста GString. Мой пробег показывает, что тогда они работают почти так же, какString adder
. Я предполагаю, что запущенный вами тест на самом деле не обрабатывает конкатенацию, поэтому он просто создает объект GString и сохраняет ссылки.StringBuilder
по-прежнему самый быстрый, если вам понадобитсяString
в какой-то момент.