使用Groovy进行string连接

在Groovy中连接string的最佳(惯用)方式是什么?

选项1:

calculateAccountNumber(bank, branch, checkDigit, account) { bank + branch + checkDigit + account } 

选项2:

 calculateAccountNumber(bank, branch, checkDigit, account) { "$bank$branch$checkDigit$account" } 

我已经在旧的Groovy网站上build立了一个有关这个主题的有趣的观点:你可以做的事情,但最好不要离开。

和Java一样,你可以用“+”符号连接string。 但是,Java只需要将“+”expression式中的两项中的一项作为一个string,而不pipe它是在第一位还是在最后一位。 Java将在你的“+”expression式的非String对象中使用toString()方法。 但是在Groovy中,你应该是安全的,你的“+”expression式的第一项以正确的方式实现了plus()方法,因为Groovy将会search和使用它。 在Groovy GDK中,只有Number和String / StringBuffer / Character类实现了连接string的plus()方法。 为了避免意外,请始终使用GStrings。

我经常使用第二种方法(使用GString模板),但是如果有更多的参数,我倾向于用${X}来包装,因为我发现它使得它更具可读性。

在这些方法上运行一些基准testing(使用Nagai Masato出色的GBench模块 )也显示模板比其他方法快:

 @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() 

这给了我在我的机器上的以下输出:

 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 

所以在可读性和速度方面,我build议使用模板;-)

注意:如果将toString()添加到GString方法的结尾以使输出types与其他度量相同,并使其成为更公平的testing,那么StringBuilderStringBuffer会优于GString方法以提高速度。 然而,由于大多数情况下GString可以用来代替String(你只需要用Map键和SQL语句谨慎操作),它可以在没有最终转换的情况下保留

添加这些testing(正如在评论中已经提到的那样)

  '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慢,但仍然比添加string快一点…

但还有更多的可读性。

编辑下面的农村编码器的评论

更新到最新的gbench,更大的string连接和一个StringBuildertesting初始化​​到一个好的大小:

 @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() 

 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