¿Cuándo debo usar StringBuilder o StringBuffer?

13

En una aplicación web de producción, mis compañeros programadores utilizaron StringBuffer en todas partes. Ahora me encargo del desarrollo de aplicaciones y correcciones. Después de leer StringBuilder y StringBuffer , he decidido reemplazar todo el código StringBuffer con StringBuilder porque no necesitamos seguridad de subprocesos en nuestros beans de datos.

Por ejemplo: (en cada bean de datos puedo ver el uso de StringBuffer)

@Override
public String toString() {
    StringBuffer sb = new StringBuffer();// replace it from StringBuilder
    sb.append(" ABCD : ").append(abcd);
    sb.append(", EFGH : ").append(efgh);
    sb.append(", IJKL : ").append(ijkl);
}

Creamos un bean de datos separado para cada sesión / solicitud. Una sesión es utilizada por un solo usuario, ningún otro usuario puede acceder a ella.

¿Debo considerar otros puntos antes de migrar?

Si hay un solo subproceso (no hay subprocesos en espera / no se buscará un nuevo subproceso para el bloqueo del objeto), se realiza igualmente con StringBuffer o StringBuilder. Sé que en el caso de StringBuffer, lleva tiempo bloquear el objeto, pero quiero saber si hay alguna diferencia de rendimiento entre ellos, excepto la retención / liberación del bloqueo del objeto.

Satish Pandey
fuente
99
Si lo usa sbcomo una variable local como en su ejemplo, entonces la seguridad de subprocesos no importa en absoluto. Incluso si miles de hilos ingresaron simultáneamente al método, cada uno tendría su propia pila de llamadas con sus propias variables locales. Los StringBuilders nunca interferirían entre sí.
fredoverflow
Siempre me he preguntado quién quiere sincronizar dos hilos a lo largo de algo como la interfaz de a StringBuffer. Nunca he visto un código así, pero estoy casi seguro de que es un mal diseño desde una perspectiva de subprocesos múltiples. Como creo que sincronizar el hilo a lo largo de la StringBufferinterfaz es una mala idea, creo que esta clase no debería existir y siempre se debe usar StringBuilder. Como otros ya mencionaron, StringBufferexiste por razones históricas.
pasztorpisti

Respuestas:

22

La única diferencia entre los dos es la sincronización utilizada en StringBuffer. La sobrecarga de la sincronización no es enorme en el gran esquema de las cosas, pero es significativa en relación con los métodos StringBuilder que no los tienen. La JVM está haciendo un trabajo que de otro modo no tendría que hacer, especialmente con solo un hilo, etc.

Si su código funciona y la gente no se queja del rendimiento, no me preocuparía. No va a obtener mucho por su dinero. Sin embargo, si está escribiendo un nuevo código o está actualizando un código que utiliza StringBuffer, le sugiero convertirlos al mismo tiempo.

Matthew Flynn
fuente
Agregaré a esto que debes tener en cuenta la seguridad del hilo heredado de los dos. StringBuilder no es seguro para subprocesos.
Martijn Verburg
2
@MartijnVerburg Es cierto, aunque se señaló en stackoverflow.com/questions/6775016/stringbuffer-is-obsolete/… que hay muy pocos casos de uso que requieran múltiples subprocesos para usar la misma instancia de un generador de cadenas.
Matthew Flynn
44
@MartijnVerburg: también hay que señalar: si usted realmente necesita hilo de seguridad entonces es probable que StringBufferno es suficiente, ya sea! Garantiza que no se frena, pero la posición en la que agrega no se puede controlar fácilmente si varios subprocesos acceden a la vez, por lo que se necesitaría otra sincronización externa.
Joachim Sauer
8

StringBuilder se agregó en un punto (Java 1.5) para ser un StringBuffer mejor y más rápido y el compilador lo utiliza bajo el capó para implementar el +operador en Strings.

Esto significa que al usar StringBuilder no puede hacer que su código se ejecute en JVM anteriores a cuando se introdujo la clase. Esto sería un problema para nosotros, por un tiempo todavía. Si siempre ejecuta lo último, no necesita preocuparse.

No pasaría por el proceso de optimización que atraviesas, aunque por las siguientes razones.

  • Fuera de los lazos apretados, la ventaja es insignificante. A menos que aparezca explícitamente como un punto de acceso en un generador de perfiles, no me molestaría.
  • Cambiar el código puede introducir errores, y debe volver a probar su aplicación a fondo. Eso puede ser mucho más costoso que vivir con una clase sincronizada en un entorno no sincronizado.
Frank Shearar
fuente
Estoy de acuerdo contigo ... todavía no puedo entender tu puntoOutside tight loops the advantage is negligible...
Satish Pandey
El mecanismo que falta en StringBuilder en comparación con StringBuffer es el intercambio de velocidad por la seguridad del hilo. Esa mejora de la velocidad es muy pequeña, por lo que solo es importante si se realiza muchas veces; este suele ser el caso en un bucle pequeño que se realiza muchas veces.