que manejo funciones ejemplos declarar concatenar caracteres cadenas cadena string groovy idioms string-concatenation gstring

string - manejo - Concatenación de cadenas con Groovy



manejo de cadenas en java (1)

¿Cuál es la mejor forma (idiomática) de concatenar cadenas en Groovy?

Opción 1:

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

Opcion 2:

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

Fundé un punto interesante sobre este tema en el viejo sitio web de Groovy: Cosas que puedes hacer, pero mejor dejarlas sin hacer.

Al igual que en Java, puede concatenar cadenas con el símbolo "+". Pero Java solo necesita que uno de los dos elementos de una expresión "+" sea una Cadena, sin importar si está en el primer lugar o en el último. Java usará el método toString () en el objeto no String de su expresión "+". Pero en Groovy, solo debes estar seguro de que el primer elemento de tu expresión "+" implementa el método más () de la manera correcta, porque Groovy lo buscará y usará. En Groovy GDK, solo las clases Number y String / StringBuffer / Character tienen el método más () implementado para concatenar cadenas. Para evitar sorpresas, siempre use GStrings.


Siempre busco el segundo método (usando la plantilla de GString), aunque cuando hay más de un par de parámetros como los que tiene, tiendo a envolverlos en ${X} ya que me parece que lo hace más legible.

Ejecutar algunos puntos de referencia (utilizando el excelente módulo de GBench de Nagai Masato ) sobre estos métodos también muestra que la creación de plantillas es más rápida que los otros métodos:

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

Eso me da la siguiente salida en mi máquina:

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

Entonces, con la legibilidad y la velocidad a favor, recomendaría la creación de plantillas ;-)

NB: Si agrega toString() al final de los métodos de GString para que el tipo de salida sea igual que las otras medidas, y lo haga una prueba más justa, StringBuilder y StringBuffer superan los métodos de GString para la velocidad. Sin embargo, como GString se puede usar en lugar de String para la mayoría de las cosas (solo se debe tener precaución con las claves Map y las sentencias SQL), en general se puede dejar sin esta conversión final.

Agregar estas pruebas (como se ha preguntado en los comentarios)

''GString template toString'' { "$foo$bar$baz".toString() } ''Readable GString template toString'' { "${foo}${bar}${baz}".toString() }

Ahora obtenemos los resultados:

String adder 514 GString template 267 Readable GString template 269 GString template toString 478 Readable GString template toString 480 StringBuilder 321 StringBuffer 369

Como puede ver (como dije), es más lento que StringBuilder o StringBuffer, pero aún un poco más rápido que agregar Strings ...

Pero aún mucho más legible.

Editar después de comentar por ruralcoder a continuación

Actualizado a la última gbench, cadenas más grandes para la concatenación y una prueba con un StringBuilder inicializado a un buen tamaño:

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

da

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