¿Hay una diferencia perceptible entre el uso String.format
y la concatenación de cadenas en Java?
Tiendo a usar, String.format
pero ocasionalmente me resbalaré y usaré una concatenación. Me preguntaba si uno era mejor que el otro.
A mi modo de ver, String.format
te da más poder para "formatear" la cadena; y la concatenación significa que no tiene que preocuparse por poner accidentalmente un% so extra o perder uno.
String.format
También es más corto.
Cuál es más legible depende de cómo funcione su cabeza.
java
string
concatenation
string.format
Omar Kooheji
fuente
fuente
Respuestas:
Sugeriría que es una mejor práctica usar
String.format()
. La razón principal es queString.format()
puede localizarse más fácilmente con texto cargado de archivos de recursos, mientras que la concatenación no puede localizarse sin producir un nuevo ejecutable con un código diferente para cada idioma.Si planea que su aplicación sea localizable, también debe acostumbrarse a especificar posiciones de argumento para sus tokens de formato:
Esto se puede localizar y cambiar los tokens de nombre y tiempo sin requerir una recompilación del ejecutable para dar cuenta de los diferentes pedidos. Con las posiciones de argumento también puede reutilizar el mismo argumento sin pasarlo dos veces a la función:
fuente
Sobre el rendimiento:
Los resultados del tiempo son los siguientes:
Por lo tanto, la concatenación es mucho más rápida que String.format.
fuente
javap -c StringTest.class
, verá que el compilador convierte "+" a StringBuilder automáticamente solo si no está en un bucle. Si la concatenación se realiza en una sola línea, es lo mismo que usar '+', pero si usamyString += "morechars";
omyString += anotherString;
en varias líneas, notará que se puede crear más de un StringBuilder, por lo que usar "+" no siempre es tan eficiente como StringBuilder.+
no se convierte,StringBuilder.append()
sino quenew StringBuilder()
sucede en cada iteración.Como hay una discusión sobre el rendimiento, pensé que agregaría una comparación que incluyera StringBuilder. De hecho, es más rápido que el concat y, naturalmente, la opción String.format.
Para hacer de esto una especie de comparación de manzanas con manzanas, ejemplifico un nuevo StringBuilder en el bucle en lugar de en el exterior (en realidad, esto es más rápido que hacer una sola instancia, muy probablemente debido a la sobrecarga de reasignación de espacio para el bucle anexar al final de Un constructor).
fuente
String
. La prueba de StringBuilder, para ser justos, necesita un paso final que convierta el contenido de StringBuilder en una cadena. Haces eso llamandobldString.toString()
. ¿Espero que esto lo explique?String s = bldString.toString();
Los tiempos eran con la concatenación y StringBuilder casi a la par con los demás:Format = 1520 millisecond
,Concatenation = 167 millisecond
,String Builder = 173 millisecond
me encontré con ellos en un bucle y un promedio de cada uno hacia fuera para conseguir un buen representante: (optimización de pre-JVM, intentará un bucle 10000+ cuando llegue el tiempo)Un problema
.format
es que pierde la seguridad de tipo estático. Puede tener muy pocos argumentos para su formato, y puede tener los tipos incorrectos para los especificadores de formato, ambos conducen a unIllegalFormatException
tiempo de ejecución , por lo que podría terminar con un código de registro que interrumpe la producción.Por el contrario, los argumentos
+
pueden ser probados por el compilador.La historia de seguridad deprintf(en el que
format
se modela la función) es largo y aterrador.fuente
Tienes tu respuesta allí mismo.
Es una cuestión de gusto personal.
La concatenación de cadenas es marginalmente más rápida, supongo, pero eso debería ser insignificante.
fuente
Aquí hay una prueba con múltiples tamaños de muestra en milisegundos.
}
fuente
Aquí está la misma prueba que la anterior con la modificación de llamar al método toString () en StringBuilder . Los resultados a continuación muestran que el enfoque StringBuilder es solo un poco más lento que la concatenación de cadenas usando el operador + .
archivo: StringTest.java
Comandos de Shell: (compila y ejecuta StringTest 5 veces)
Resultados:
fuente
String.format()
es más que simplemente concatenar cadenas. Por ejemplo, puede mostrar números en un entorno local específico medianteString.format()
.Sin embargo, si no le importa la localización, no hay diferencia funcional. Quizás el uno sea más rápido que el otro, pero en la mayoría de los casos será insignificante.
fuente
En general, se debe preferir la concatenación de cadenas
String.format
. Este último tiene dos desventajas principales:Por punto 1, quiero decir que no es posible entender lo que
String.format()
está haciendo una llamada en un solo paso secuencial. Uno se ve obligado a ir y venir entre la cadena de formato y los argumentos, mientras cuenta la posición de los argumentos. Para concatenaciones cortas, esto no es un gran problema. Sin embargo, en estos casos, la concatenación de cadenas es menos detallada.Por punto 2, quiero decir que la parte importante del proceso de construcción está codificada en la cadena de formato (usando un DSL). El uso de cadenas para representar código tiene muchas desventajas. No es intrínsecamente seguro para escribir y complica el resaltado de sintaxis, el análisis de código, la optimización, etc.
Por supuesto, cuando se usan herramientas o marcos externos al lenguaje Java, pueden entrar en juego nuevos factores.
fuente
No he hecho ningún punto de referencia específico, pero creo que la concatenación puede ser más rápida. String.format () crea un nuevo formateador que, a su vez, crea un nuevo StringBuilder (con un tamaño de solo 16 caracteres). Esa es una buena cantidad de gastos generales, especialmente si está formateando una cadena más larga y StringBuilder sigue teniendo que cambiar el tamaño.
Sin embargo, la concatenación es menos útil y más difícil de leer. Como siempre, vale la pena hacer un punto de referencia en su código para ver cuál es mejor. Las diferencias pueden ser insignificantes en la aplicación del servidor después de que sus paquetes de recursos, configuraciones regionales, etc. se carguen en la memoria y se JITTE el código.
Tal vez como mejor práctica, sería una buena idea crear su propio formateador con un StringBuilder (Appendable) y Locale de tamaño adecuado y usarlo si tiene mucho formato para hacer.
fuente
Podría haber una diferencia perceptible.
String.format
es bastante complejo y usa una expresión regular debajo, así que no acostumbres a usarlo en todas partes, sino solo donde lo necesites.StringBuilder
sería un orden de magnitud más rápido (como ya señaló alguien aquí).fuente
Creo que podemos seguir,
MessageFormat.format
ya que debería ser bueno tanto en la legibilidad como en los aspectos de rendimiento.Usé el mismo programa que usó Icaro en su respuesta anterior y lo mejoré con un código adjunto para
MessageFormat
explicar los números de rendimiento.ACTUALIZACIONES:
Según el informe SonarLint, las cadenas de formato de estilo Printf deben usarse correctamente (calamar: S3457)
Debido a que las
printf-style
cadenas de formato se interpretan en tiempo de ejecución, en lugar de ser validadas por el compilador, pueden contener errores que provocan la creación de cadenas incorrectas. Esta regla valida estáticamente la correlación deprintf-style
las cadenas de formato a sus argumentos al llamar a los métodos de formato (...) dejava.util.Formatter
,java.lang.String
,java.io.PrintStream
,MessageFormat
, yjava.io.PrintWriter
las clases y losprintf(...)
métodos de lajava.io.PrintStream
ojava.io.PrintWriter
las clases.Reemplazo el estilo printf con las llaves y obtuve resultados interesantes como a continuación.
Mi conclusión:
como destaqué anteriormente, usar String.format con llaves debe ser una buena opción para obtener beneficios de buena legibilidad y también rendimiento.
fuente
No puede comparar String Concatenation y String.Format por el programa anterior.
Puede intentar esto también intercambiando la posición de usar su String.Format and Concatenation en su bloque de código como el siguiente
Te sorprenderá ver que el formato funciona más rápido aquí. Esto se debe a que los objetos iniciales creados pueden no liberarse y puede haber un problema con la asignación de memoria y, por lo tanto, con el rendimiento.
fuente
Toma un poco de tiempo acostumbrarse a String.Format, pero vale la pena en la mayoría de los casos. En el mundo de NRA (nunca repita nada) es extremadamente útil mantener sus mensajes tokenizados (registro o usuario) en una biblioteca Constant (prefiero lo que equivale a una clase estática) y llamarlos según sea necesario con String.Format independientemente de si están localizando o no. Intentar utilizar una biblioteca de este tipo con un método de concatenación es más difícil de leer, solucionar problemas, corregir y administrar con cualquier enfoque que requiera concatenación. El reemplazo es una opción, pero dudo que sea eficiente. Después de años de uso, mi mayor problema con String.Format es que la duración de la llamada es inconvenientemente larga cuando la paso a otra función (como Msg), pero eso es fácil de solucionar con una función personalizada para servir como un alias .
fuente