For large lists (obviously not the case here), it is more efficient to form a line directly:
def sb = ["test1", "test2", "test3"].inject(new StringBuilder()) { builder, value ->
builder << "pre/${value} "
}
sb.setLength(sb.size() - 1)
, . 10 , :
import java.lang.management.ManagementFactory
def threadMX = ManagementFactory.threadMXBean
assert threadMX.currentThreadCpuTimeSupported
threadMX.threadCpuTimeEnabled = true
def timeCPU = { Closure c ->
def start = threadMX.currentThreadCpuTime
def result = c.call()
def end = threadMX.currentThreadCpuTime
println "CPU time: ${(end - start)/1000000000} s"
}
def timeReal = { Closure c ->
def start = System.currentTimeMillis()
def result = c.call(args)
def end = System.currentTimeMillis()
println "Elapsed time: ${(end - start)/1000} s"
result
}
def theList = (0..<10000000). collect { it.toString() }
[CPU:timeCPU, Real:timeReal].each { label, time ->
println "\n\n$label Time"
print ("Mine: ".padLeft(20))
def s2 = time {
def sb = theList.inject(new StringBuilder()) { builder, value ->
builder << "pre/${value} "
}
sb.setLength(sb.size() - 1)
sb.toString()
}
print ("cfrick's: ".padLeft(20))
def s3 = time {
def sb = theList.inject(new StringBuilder()) { builder, value ->
builder << "pre/" << value << " "
}
sb.setLength(sb.size() - 1)
sb.toString()
}
print ("Opal's: ".padLeft(20))
def s1 = time { theList.collect { "pre/${it}" }.join(" ") }
print "Opal w/o GString: "
def s4 = time { theList.collect { "pre/" + it }.join(" ") }
assert s1 == s2 && s2 == s3 && s3 == s4
}
:
CPU Time
Mine: CPU time: 12.8076821 s
cfrick's: CPU time: 2.1684139 s
Opal's: CPU time: 3.5724229 s
Opal w/o GString: CPU time: 3.1356201 s
Real Time
Mine: Elapsed time: 15.826 s
cfrick's: Elapsed time: 3.587 s
Opal's: Elapsed time: 8.906 s
Opal w/o GString: Elapsed time: 6.296 s