example ejemplo java javac stringbuilder stringbuffer jdk1.4

ejemplo - stringbuffer java example



¿Cuándo se introdujo la optimización Javac StringBuilder/StringBuffer? (4)

Aquí hay una cita de la especificación de idioma de la versión 1 :

Una implementación puede optar por realizar la conversión y la concatenación en un solo paso para evitar crear y luego descartar un objeto String intermedio. Para aumentar el rendimiento de la concatenación de cadenas repetidas, un compilador de Java puede usar la clase StringBuffer (§20.13) o una técnica similar para reducir el número de objetos de String intermedios que se crean mediante la evaluación de una expresión.

En el momento, tenían StringBuffer lugar de StringBuilder .

También una cita de StringBuffer de JDK1.0.2:

Esta clase es un búfer de crecimiento para los personajes. Se utiliza principalmente para crear cadenas. El compilador lo usa para implementar el operador "+".

Sé que el compilador Javac puede transformar la concatenación de cadenas usando StringBuilder / StringBuffer , y tengo curiosidad por saber a partir de qué versión se introdujo este cambio.

Estoy usando este código de ejemplo:

public class Main { public static void main(String[] args) { String a = args[0]; String s = "a"; s = s + a; s = s + "b"; s = s + "c"; s = s + "d"; s = s + "e"; System.out.println(s); } }

Hasta ahora he probado con javac 1.8.0_121 , javac 1.6.0_20 , javac 1.5.0_22 y java 1.4.2_19 .

Aquí hay una muestra del 1.4.2_19 de 1.4.2_19 que veo usando javap -c de 1.4.2_19 :

6: astore_2 7: new #3; //class StringBuffer 10: dup 11: invokespecial #4; //Method java/lang/StringBuffer."<init>":()V 14: aload_2 15: invokevirtual #5; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer; 18: aload_1 19: invokevirtual #5; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer; 22: invokevirtual #6; //Method java/lang/StringBuffer.toString:()Ljava/lang/String;

Las 4 versiones parecen estar usando la optimización StringBuilder / StringBuffer, así que tengo curiosidad por saber a partir de qué versión Javac se introdujo este cambio.


He consultado la Especificación del lenguaje Java, Primera edición (desde 1996). No es fácil de encontrar, pero aquí está . El pasaje sobre la optimización de la concatenación estaba allí incluso entonces:

Una implementación puede optar por realizar la conversión y la concatenación en un solo paso para evitar crear y luego descartar un objeto String intermedio. Para aumentar el rendimiento de la concatenación de cadenas repetidas, un compilador de Java puede usar la clase StringBuffer (§20.13) o una técnica similar para reducir el número de objetos de cadena intermedios que se crean mediante la evaluación de una expresión.

La especificación perteneciente a StringBuffer entonces, pero StringBuilder (a la que se refiere la redacción actual de JLS) podría considerarse de mejor rendimiento porque sus métodos no están sincronizados.

Esto, sin embargo, no significa que uno deba confiar en la optimización ya que siempre está en su lugar. La concatenación de cadenas en los bucles no se optimizará, por ejemplo.



Esto no responde a la pregunta , pero quiero simplemente agregar al punto general de que en jdk-9 este StringBuilder::append es una de las estrategias permitidas , pero no la predeterminada.

private enum Strategy { /** * Bytecode generator, calling into {@link java.lang.StringBuilder}. */ BC_SB, /** * Bytecode generator, calling into {@link java.lang.StringBuilder}; * but trying to estimate the required storage. */ BC_SB_SIZED, /** * Bytecode generator, calling into {@link java.lang.StringBuilder}; * but computing the required storage exactly. */ BC_SB_SIZED_EXACT, /** * MethodHandle-based generator, that in the end calls into {@link java.lang.StringBuilder}. * This strategy also tries to estimate the required storage. */ MH_SB_SIZED, /** * MethodHandle-based generator, that in the end calls into {@link java.lang.StringBuilder}. * This strategy also estimate the required storage exactly. */ MH_SB_SIZED_EXACT, /** * MethodHandle-based generator, that constructs its own byte[] array from * the arguments. It computes the required storage exactly. */ MH_INLINE_SIZED_EXACT }

En realidad, es un invokedynamic para la concatenación de cadenas, por lo que su implementación ahora es específica de JRE, no del compilador. La estrategia predeterminada por cierto es: MH_INLINE_SIZED_EXACT