Я всегда выбираю второй метод (с использованием шаблона 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
в какой-то момент.GString
«как есть», в какой-то момент его нужно преобразовать в истинноеString
(даже просто для того, чтобы распечатать), поэтому истинное время будет последним установленным. В конце концов, когда время так близко, удобочитаемостьGString
шаблонов бьетStringBuilder
ключом, так что это спорный вопрос. :-)def my_string = "some string" println "here: " + my_string
Не совсем уверен, почему приведенный выше ответ должен входить в тесты, строковые буферы, тесты и т. Д.
источник
Воспроизведение ответа tim_yates на текущем оборудовании и добавление методов leftShift () и concat () для проверки результатов:
'String leftShift' { foo << bar << baz } 'String concat' { foo.concat(bar) .concat(baz) .toString() }
Результат показывает, что concat () является более быстрым решением для чистой String, но если вы можете обрабатывать GString где-то еще, шаблон GString все еще впереди, в то время как почетное упоминание должно быть уделено leftShift () (побитовый оператор) и StringBuffer () с начальным распределение:
Environment =========== * Groovy: 2.4.8 * JVM: OpenJDK 64-Bit Server VM (25.191-b12, Oracle Corporation) * JRE: 1.8.0_191 * Total Memory: 238 MB * Maximum Memory: 3504 MB * OS: Linux (4.19.13-300.fc29.x86_64, amd64) Options ======= * Warm Up: Auto (- 60 sec) * CPU Time Measurement: On user system cpu real String adder 453 7 460 469 String leftShift 287 2 289 295 String concat 169 1 170 173 GString template 24 0 24 24 Readable GString template 32 0 32 32 GString template toString 400 0 400 406 Readable GString template toString 412 0 412 419 StringBuilder 325 3 328 334 StringBuffer 390 1 391 398 StringBuffer with Allocation 259 1 260 265
источник