2009-12-03 15 views
16

normalmente crear una cadena en Java de la siguiente manera:¿Existe una "forma más rápida" de construir cadenas en Java?

String foo = "123456";

Sin embargo, mi profesor ha insistido para mí que la formación de una cadena utilizando el método format, como tan:

String foo = String.format("%s", 123456);

es mucho más rápido .

Además, dice que el uso de la clase StringBuilder es aún más rápido.

 
StringBuilder sb = new StringBuilder(); 
String foo = sb.append(String.format("%s", 123456)).toString(); 



¿Cuál es el método más rápido para crear una cadena, si hay siquiera es uno?

No pudieron ser 100% precisas ya que podría no recordarlas por completo.

+0

Buena pregunta, ¿esto es autoboxing? Sé que Integer foo = 1 es más lento que Integer foo = Integer.valueOf (1); – Trick

+7

Siendo un estudiante, sería genial si se le ocurre una forma de probar su teoría. ¿Puedes escribir una clase de Java que pueda construir 100000 strings/stringbuffers, etc. y medir el tiempo? –

+13

Le diría a su profesor que en el mundo real, la muy pequeña ventaja de rendimiento posible está muy por encima de la legibilidad. Además, el código siempre debe escribirse para que funcione primero, lo más simple y fácil posible, y luego se optimiza SI es necesario (que normalmente no existe). –

Respuesta

24

Si sólo hay una cadena a continuación:

String foo = "123456"; 

es el más rápido. Notarás que la línea String.format tiene "%s%" declarado en ella, así que no veo cómo el conferencista podría pensar que era más rápido. Además, tienes una llamada de método en la parte superior.

Sin embargo, si está compilando una cadena a lo largo del tiempo, como en un bucle for, entonces querrá usar un StringBuilder. Si tuviera que usar +=, entonces está construyendo una nueva cadena cada vez que se llame a+=. StringBuilder es mucho más rápido ya que contiene un búfer y lo agrega cada vez que llamas al append.

+0

mis pensamientos exactamente. – pstanton

+1

Sí, si declaras una cadena literal, entonces simplemente incrustarla es obviamente la forma más rápida. Tuve un prof de lenguaje de programación una vez que le dije a la clase que Java no tenía punteros, por lo que no se podían crear cosas como listas enlazadas, pensó que todas las colecciones de Java se implementaron en C o algo así. Hice que otro profesor dijera que los sitios web 'seguros' eran los que terminaban en '.shtml' (en lugar de comenzar con https). A veces simplemente no saben de qué están hablando. –

+2

Además, en un ciclo cerrado, podría estar creando un GRAN cantidad de cuerdas, cada una un poco más grande que la anterior. Esto también es cierto en C# (también .Net). También estoy de acuerdo con el comentario de Eric Wendelin de que debes escribir una prueba para ver. No le cuente a su profesional las opiniones de las personas sobre la interwebz cuando podría mostrarle una prueba documentada de si tiene razón o no. Me gustaría hacer una serie de casos de prueba: velocidad para crear una cadena a través de cada método, velocidad para crear lotes en un bucle, etc. – jeffa00

8
String foo = "some string literal"; 

es sin duda la forma más rápida de hacer una cadena. Está incrustado en el archivo .class y es una simple búsqueda de memoria para recuperar.

El uso de String.format cuando no tiene nada que realmente formatear simplemente se ve feo y puede causar que los desarrolladores más jóvenes lloren.

Si la cadena se va a modificar, entonces StringBuilder es el mejor desde Strings es immutable.

+14

Usar String.format cuando no tiene nada que realmente formatear probablemente también haga que los desarrolladores senior lloren también. – JasCav

4

Si su cadena es conocida en tiempo de compilación, entonces usar un literal es mejor: String foo = "123456";.

Si su serie no se conoce en tiempo de compilación y se compone de una agregación de cadenas más pequeñas, StringBuilder suele ser el camino a seguir (¡pero tenga cuidado con la seguridad de los hilos!).

Usando String foo = String.format("%s", 123456);podría reducir el tamaño de sus .class' y hacer la clase de carga que un poquito más rápido, pero eso sería extremadamente agresivo de sintonización (extremo) de memoria no ^^.

4

En el segundo ejemplo, usando:

String foo = String.format("%s", 123456); 

no te comprar nada; 123456 ya es un valor constante, ¿por qué no simplemente asignar foo = "123456"?Para cadenas constantes, no hay mejor manera.

Si va a crear una cadena de múltiples piezas que se adjunta juntos en tiempo de ejecución, utilice StringBuffer o StringBuilder (siendo los primeros flujos seguros).

3

Como se ha señalado, si sólo está la construcción de una sola cadena sin concatenación, sólo tiene que utilizar cuerdas.

Para la concatenación de múltiples bits en una cadena grande, StringBuffer es más lento que StringBuilder, pero StringBuffer se sincroniza. Si no necesita sincronización, StringBuilder.

11

Toda esta discusión es discutible. Lea este artículo de Jeff, es decir, el tipo que creó Stack Overflow.

The Sad Tragedy of Micro-Optimization Theater

Por favor refiérase a su instructor a este mensaje y pedirle que deje de arruinar su cerebro/ella de los estudiantes con información inútil. Las optimizaciones algorítmicas son donde su código vivirá o morirá, no con qué método use para construir cadenas. En cualquier caso, StringBuilder y el formateador String tienen que ejecutar CÓDIGO REAL con MEMORIA REAL, si solo construyes una cadena, se aparta durante el tiempo de compilación y está lista para ser utilizada cuando la necesites, en esencia, tiene 0 run- costo de tiempo, mientras que las otras opciones tienen un costo real, ya que el código realmente necesita ser ejecutado.

+1

No ser demasiado quisquilloso, pero creo que quiere decir que la discusión es "discutible". Aunque también es "mudo" ya que SO no tiene sonidos ...;) – jasonh

+2

¡Optimicemos esta publicación! :) – Tim

+0

Gracias por la corrección de errores de ortografía. – Michael

1

El primer ejemplo que dio fue el más rápido y el más simple. Usa eso.

Cada pieza de código que agregó en esos ejemplos lo hace significativamente más lento y más difícil de leer.

sugeriría ejemplo 2 es al menos 10-100x más lento que el ejemplo 1 y el ejemplo 3 es aproximadamente 2 veces más lento que el ejemplo 2.

¿Su procesador proporciona ninguna justificación para esta afirmación?

BTW: Su primer ejemplo no construye una cadena en absoluto (que es por eso que es más rápido), sólo se le entrega una cadena sentado en la piscina constante de cadena.

2

¿Estás 100% seguro de que el instructor no estaba hablando de algo así como:

String foo = "" + 123456; 

veo a mis estudiantes hacen ese tipo de cosas "todo el tiempo" (un puñado hará que cada término). La razón por la que lo hacen es que algún libro les mostró cómo hacerlo de esa manera. Sacude la cabeza y el puño a los escritores de libros perezosos!

+0

Pensé que era un atajo idiomático para 'foo = String.valueOf (int_var)'. Supongo que hay algo de sobrecarga para crear (referencia) cadena vacía, pero además de esto, ¿qué tiene de malo? –

+0

No es lo más claro de hacer. También String.valueOf (int) llama a Integer.toString (int) (no es un requisito, pero eso es lo que hace el JDK). Si el compilador hace eso, será más lento, dependiendo del entorno, que llamar a Integer.toString (int). Integer.toString (int) es más claro para mí que "" + int y más obvio. – TofuBeer

14

poco fuera de tema, pero me gustaría que todo el "deber-no-uso-más-a-concatenar-cuerdas-en-Java" mito se iría. Si bien podría haber sido cierto en las primeras versiones de Java que StringBuffer era más rápido y "+ era malo", ciertamente no es cierto en las JVM modernas que se están ocupando de muchas optimizaciones.

Por ejemplo, ¿qué es más rápido?

String s = "abc" + "def"; 

o

StringBuffer buf = new StringBuffer(); 
    buf.append("abc"); 
    buf.append("def"); 
    String s = buf.toString(); 

la respuesta es la primera. La JVM reconoce que esta es una constante de cadena y realmente colocará "abcdef" en el grupo de cadenas, mientras que la versión "stringbuffer optimizado" causará la creación de un objeto StringBuffer adicional.

Otra optimización JVM es

String s = onestring + " concat " + anotherstring; 

Cuando la JVM se resuelve cuál será la mejor manera de concatenar. En JDK 5, esto significa que un StringBuilder se usará internamente y será más rápido que usar un buffer de cadena.

Pero como otras respuestas han dicho, el "123456" constante en su pregunta es sin duda la forma más rápida y su profesor debería volver a ser un estudiante :-)

Y sí, he tenido la triste para verificar esto mirando el bytecode de Java ...

+0

Más comentarios de Gyaan a su comentario "Un poco fuera de tema". En otro escenario, crear cadenas usando StringBuilder sería más eficiente. Si está concatenando diferentes cadenas mediante for loop, que generalmente es el caso como String simple = ""; for (contador int = 0; contador <100000; contador ++) { simple + = contador; } // Esta simple operación tomó alrededor de 12 segundos para completarse. StringBuffer buffer = new StringBuffer(); para (contador int = 0; contador <100000; contador ++) { buffer.append (buffer); } // ¡Esto tomó solo 14 ms! – mac

+0

Vaya, me acabo de dar cuenta de que estoy haciendo hincapié en la respuesta de part2 o jasonh. – mac

Cuestiones relacionadas