Есть 3 варианта:
1. GString интерполяция
def presentationType = "${feedDisplayType != null && !feedDisplayType.isEmpty() ? feedDisplayType + ', ' : ''}${moduleType != null && !moduleType.isEmpty() ? moduleType + ', ' : ''}${cellType != null && !cellType.isEmpty() ? cellType : ''}".toString()
2. Использование StringBuilder
def sb = new StringBuilder()
if (feedDisplayType != null && !feedDisplayType.isEmpty()) {
sb.append(feedDisplayType)
sb.append(', ')
}
if (moduleType != null && !moduleType.isEmpty()) {
sb.append(moduleType)
sb.append(', ')
}
if (cellType != null && !cellType.isEmpty()) {
sb.append(cellType)
}
def presentationType = sb.toString()
3. Присоединение к списку с ,
в качестве разделителя
def presentationType = [feedDisplayType, moduleType, cellType].findAll { str -> str != null && !str.isEmpty() }.join(', ')
Benchmark
Прежде чем перейти к заключению, давайте протестируем все 3 метода, используя GBench tool:
@Grab(group='org.gperfutils', module='gbench', version='0.4.3-groovy-2.4')
def feedDisplayType = 'test'
def moduleType = null
def cellType = ''
def r = benchmark {
'GString method' {
def presentationType = "${feedDisplayType != null && !feedDisplayType.isEmpty() ? feedDisplayType + ', ' : ''}${moduleType != null && !moduleType.isEmpty() ? moduleType + ', ' : ''}${cellType != null && !cellType.isEmpty() ? cellType : ''}".toString()
}
'StringBuilder method' {
def sb = new StringBuilder()
if (feedDisplayType != null && !feedDisplayType.isEmpty()) {
sb.append(feedDisplayType)
sb.append(', ')
}
if (moduleType != null && !moduleType.isEmpty()) {
sb.append(moduleType)
sb.append(', ')
}
if (cellType != null && !cellType.isEmpty()) {
sb.append(cellType)
}
def presentationType = sb.toString()
}
'Join list method' {
def presentationType = [feedDisplayType, moduleType, cellType].findAll { str -> str != null && !str.isEmpty() }.join(', ')
}
}
r.prettyPrint()
выход
Environment
===========
* Groovy: 2.4.12
* JVM: OpenJDK 64-Bit Server VM (25.171-b10, Oracle Corporation)
* JRE: 1.8.0_171
* Total Memory: 236 MB
* Maximum Memory: 3497 MB
* OS: Linux (4.16.5-200.fc27.x86_64, amd64)
Options
=======
* Warm Up: Auto (- 60 sec)
* CPU Time Measurement: On
user system cpu real
GString method 265 2 267 268
StringBuilder method 72 4 76 77
Join list method 484 3 487 495
Заключение
Если вы стремитесь к максимальной пропускной способности, метод StringBuilder
является лучшим (среднее время 77 наносекунд).
GString
метод в несколько раз медленнее, чем StringBuilder
, и он намного менее читабелен из-за всех операторов условия внутри одной строки GString. Это также довольно подвержено ошибкам - в этом случае легко допустить ошибку при интерполяции String.
Метод присоединения к списку является самым медленным (только в 2 раза медленнее, чем метод GString), но он является самым чистым. И это все еще довольно быстро - в большинстве случаев приемлемо 495 наносекунд. Конечно, оптимизация зависит от конкретного случая использования - если вам нужно выполнять эту часть кода миллион раз в секунду, тогда вместо этого использование StringBuilder
имеет гораздо больший смысл.
Базовые угловые чехлы
Чтобы завершить этот пример, давайте также посмотрим на угловые случаи в тестировании производительности Мы используем один и тот же код с разным вводом.
Введите:
def feedDisplayType = 'lorem ipsum'
def moduleType = 'dolor sit amet'
def cellType = '123456789'
Выход:
user system cpu real
GString method 387 1 388 390
StringBuilder method 170 0 170 175
Join list method 847 6 853 859
Введите:
def feedDisplayType = ''
def moduleType = ''
def cellType = ''
Выход:
user system cpu real
GString method 237 5 242 242
StringBuilder method 44 0 44 44
Join list method 441 0 441 446