Pregunta

¿Funciona la cadena de la inmutabilidad de declaración, o mediante cadenas dentro de una declaración?

Por ejemplo, entiendo que el siguiente código asignará dos cadenas en el montón.

string s = "hello ";
s += "world!";

"Hola" permanecerá en el montón hasta basura recogida; y ahora es referencias "Hello World!" en el montón. Sin embargo, el número de cadenas tiene la siguiente línea asigna en el montón ... 1 o 2? Además, ¿hay una herramienta / modo de verificar los resultados?

string s = "goodbye " + "cruel world!";
¿Fue útil?

Solución

El compilador tiene un tratamiento especial para la concatenación de cadenas, por lo que el segundo ejemplo es solamente siempre un cadena. Y "internar" significa que incluso si se ejecuta esta línea 20000 veces no es tan sólo del 1 cadena.

Re comprobar los resultados ... la manera más fácil (en este caso) es probable que mirar en el reflector:

.method private hidebysig static void Main() cil managed
{
    .entrypoint
    .maxstack 1
    .locals init (
        [0] string s)
    L_0000: ldstr "goodbye cruel world!"
    L_0005: stloc.0 
    L_0006: ldloc.0 
    L_0007: call void [mscorlib]System.Console::WriteLine(string)
    L_000c: ret 
}

Como se puede ver (ldstr), el compilador ha hecho esto para usted ya.

Otros consejos

Las cadenas literales están internados esto significa que "hello " hace no residir en el montón, pero en el segmento de datos [ver comentarios] de la progam (y por lo tanto no es elegible para la recolección de basura), lo mismo que "world", como para que puedan "hello world" también se internados, si el compilador es suficientemente inteligente.

"goodbye cruel world" , sean internados desde concatenación de cadenas literales se trató algo por el compilador.


Editar No estoy seguro acerca de la declaración de segmento de datos, consulte esta pregunta para más información.

En realidad, probablemente, 3. una cadena const para "adiós", una cadena const para "mundo cruel", y luego una nueva cadena para el resultado.

Puede salir de dudas por mirar el código generado. Depende del compilador, (y, de hecho, en el lenguaje, esto no es obvio), pero se puede leer la salida de g ++ utilizando la opción -a (creo, compruebe la página del manual) para obtener el código intermedio .

No confía en lo que "saber" acerca de las cadenas. Es posible mirar a través del código fuente de la aplicación de la cadena. Por ejemplo, su ejemplo:

string s = "goodbye " + "cruel world!";

En Java asignaría una sola cadena. Java juega algunos trucos muy lindo y sería difícil de burlar - nunca optimizar hasta que necesite

Actualmente, sin embargo, por lo que yo sé, el uso de este:

String s="";
for(int i=0;i<1000;i++)
    s+=" ";

para crear una cadena de 1.000 espacio todavía tiende a ser extremadamente ineficiente

Al añadir en un bucle es bastante malo, pero por lo demás es probable que sea tan eficiente como StringBuilder.

Tenga cuidado aquí, porque el compilador puede hacer algunas optimizaciones muy diferentes cuando los valores de cadena se conocen en tiempo de compilación. Si las cadenas que está utilizando no se conocen hasta el tiempo de ejecución (sacado de un archivo de configuración, base de datos o la entrada del usuario) verás algunas muy diferente IL.

Si sólo vamos a hacer una o dos concatenaciones de cadenas que no me preocupe por eso.

Sin embargo, si usted tiene gran cantidad de concatenaciones, o si tiene un bucle, a continuación, que debe de tomar precauciones. En el mundo Java que te permite utilizar insteads StringBuffer de la concatenación de cadenas.

Si no se trata sólo de una línea, la concatenación de dos cadenas puede llevarse a cabo haciendo la primera cadena en un StringBuffer, haciendo la concatenación, y devolver la cadena de resultado.

Creación de la StringBuffer usted mismo puede parecer demasiado difícil, pero eso es lo que va a suceder de todos modos .-

Por supuesto no prematuramente optimizar, pero no descartan lo mal que pueden ser de cadena concatonations performant. No es la creación del objeto, pero el trabajo de GC que causa.

Hay un laboratorio de (ingeniero de soporte ASP.NET) el blog de Tess Ferrnandez que muestran una ejemplo (y no extrema, concedida) de cómo concatonation cadena puede llevar un servidor de rodillas .

Si el compilador es "inteligente", que estará a sólo una cadena con "adiós mundo cruel!"

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top