example java stringbuilder

example - stringbuilder replace java



StringBuilder-Restablecer o crear un nuevo (8)

Bueno, hay una mayor diferencia entre los dos. El primero conserva la capacidad que tenía antes de eliminar los caracteres (es decir, stringBuilder.capacity() ), mientras que el segundo crea un nuevo StringBuilder con la capacidad predeterminada, 16. Por supuesto, solo puede pasar stringBuilder.capacity() como un argumento al constructor, pero es importante entender la distinción aquí, sin embargo.

En cualquier caso, dudo mucho que veas una diferencia de rendimiento sustancial entre estas dos variantes, así que elige la que sea más legible y más fácil de administrar. Solo cuando haya determinado de manera concluyente que esto está causando algún tipo de cuello de botella, debe cambiar su enfoque.

Tengo la condición de que un StringBuilder siga almacenando líneas que coincidan con un patrón de un archivo plano grande (100 de MB). Sin embargo, después de alcanzar una condición, escribo el contenido de la variable StringBuilder en un archivo de texto.

Ahora me pregunto si debería usar la misma variable restableciendo el objeto ->

stringBuilder.delete(0,stringBuilder.length())

O

stringBuilder=new StringBuilder();

Por favor, sugiera qué cree usted que es mejor en lo que respecta a los problemas de rendimiento y OOM.


Creo que StringBuilder#delete(start, end) sigue siendo una llamada costosa, debes hacer:

stringBuilder.setLength(0);

para restablecerlo.

ACTUALIZACIÓN: Después de ver el código fuente de StringBuilder Parece que setLength(int) deja el búfer intacto y es mejor llamar: StringBuilder#trimToSize() después de la llamada anterior que attempts to reduce storage used for the character sequence .

Entonces algo como esto sería más eficiente:

stringBuilder.setLength(0); // set length of buffer to 0 stringBuilder.trimToSize(); // trim the underlying buffer


Es más barato reutilizar el objeto creado que asignar uno nuevo, siempre. También evita el trabajo adicional para el recolector de basura, ya que está manejando solo un objeto.

La forma más rápida es:

stringBuilder.setLength(0);


Idealmente, deberíamos usar el new StringBuilder() Excavando un poco en la clase StringBuilder de grepcode puedo conocer lo siguiente.

Creando nuevo objeto:

/** * Creates an AbstractStringBuilder of the specified capacity. */ AbstractStringBuilder(int capacity) { value = new char[capacity]; }

El nuevo StringBuilder () crea un nuevo objeto con una capacidad inicial de matriz de caracteres. Arriba: aquí se llamará a GC para borrar un objeto más antiguo.

Utilizando eliminar:

public AbstractStringBuilder delete(int start, int end) { if (start < 0) throw new StringIndexOutOfBoundsException(start); if (end > count) end = count; if (start > end) throw new StringIndexOutOfBoundsException(); int len = end - start; if (len > 0) { System.arraycopy(value, start+len, value, start, count-end); count -= len; } return this; }

Usando Length y TrimToSize:

public void trimToSize() { if (count < value.length) { value = Arrays.copyOf(value, count); } }

Llamará a copyOf de la clase array

public static char [] copyOf (char [] original, int newLength) {char [] copy = new char [newLength]; System.arraycopy (original, 0, copy, 0, Math.min (original.length, newLength)); copia de retorno }

Ahora también llamará a System.arrayCopy que es un método nativo. Ahora, si ve en copyOf, estamos creando un nuevo charArray nuevamente de 0 de longitud, y cuando intentemos agregarle datos nuevamente, se llamará expandir porque la longitud actual sería 0 . Así que creo que es mejor llamar al nuevo StringBuilder ()

Puedes ver el código de arriba en grepcode

PS: @ user3241961 es escritura en el caso de que esté utilizando la referencia de este objeto, entonces el nuevo requerirá configurarlo nuevamente


Imho, sugeriría usar nuevo:

stringBuilder = new StringBuilder();

Nunca he oído hablar de una pérdida de memoria en StringBuilder, pero cuando realmente superas los límites, nunca sabes. Cubriría mis apuestas contra él usando una nueva instancia cada vez.

En el peor de los casos, quizás pierda algo de eficiencia y la gc haga ejercicio, pero descarta la posibilidad de OOM.

Por eso, y también por razones de claridad, yo personalmente tomaría el nuevo enfoque.


Si se encuentra en un bucle estrecho y continuará en ese bucle después de escribir los datos en el archivo, definitivamente debe reutilizar StringBuilder. No hay razón para no hacerlo y es mejor que batir el GC. Si estuviera escribiendo esto en C o C ++, reutilizaría el búfer.

Además, si bien es cierto que el método delete (...) llama a System.arraycopy, el número de bytes copiados es 0, por lo que es insignificante.

Ah, alguien me mencionó que hay un método setLength (...) que es la forma más rápida de reutilizar el búfer.


Una diferencia fundamental es que sb.delete mantiene la referencia, mientras que el constructor la pierde.

Si su SB es un argumento de método, y se supone que debe usarse para devolver el contenido a la persona que llama, debe usar sb.delete. La persona que llama tiene la referencia original.


Yo usaría:

stringBuilder = new StringBuilder();

porque si lo llena con una gran cantidad de datos, llame a stringBuilder.setLength(0); no desasignará la matriz de respaldo, por lo que podría ver que el uso de memoria se mantiene alto innecesariamente.

Además, es más fácil de leer y entender.