c# - variable - ¿Por qué solo cadenas literales guardadas en el grupo interno de forma predeterminada?
manejo de cadenas programacion (3)
La respuesta corta: internar cadenas literales es barato en tiempo de ejecución y ahorra memoria . Internar cadenas no literales es costoso en tiempo de ejecución y, por lo tanto, ahorra una pequeña cantidad de memoria a cambio de hacer que los casos comunes sean mucho más lentos .
El costo de la "optimización" de las cadenas de internado en tiempo de ejecución no paga por el beneficio, y por lo tanto no es realmente una optimización. El costo de internar cadenas literales es barato y, por lo tanto, paga por el beneficio.
Aquí respondo a tu pregunta con más detalle:
http://blogs.msdn.com/b/ericlippert/archive/2009/09/28/string-interning-and-string-empty.aspx
¿Por qué, por defecto, solo las cadenas literales se guardan en el grupo interno?
Ejemplo de MSDN :
String s1 = "MyTest";
String s2 = new StringBuilder().Append("My").Append("Test").ToString();
String s3 = String.Intern(s2);
Console.WriteLine("s1 == ''{0}''", s1);
Console.WriteLine("s2 == ''{0}''", s2);
Console.WriteLine("s3 == ''{0}''", s3);
Console.WriteLine("Is s2 the same reference as s1?: {0}", (Object)s2==(Object)s1);
Console.WriteLine("Is s3 the same reference as s1?: {0}", (Object)s3==(Object)s1);
/*
This example produces the following results:
s1 == ''MyTest''
s2 == ''MyTest''
s3 == ''MyTest''
Is s2 the same reference as s1?: False
Is s3 the same reference as s1?: True
*/
Las cadenas de internado no proporcionarían casi ningún beneficio en la mayoría de los escenarios de uso de cadenas, incluso si uno tuviera un grupo de internamiento de referencia débil de costo cero (la implementación de internado ideal). Para que el internado de cadenas ofrezca algún beneficio, es necesario que se mantengan varias referencias a cadenas de coincidencia iguales durante un tiempo razonablemente "largo".
Considere los siguientes dos programas:
- Ingrese 100,000 líneas desde un archivo de texto, cada uno con un texto arbitrario, y luego 100,000 números de cinco dígitos. Considere cada número leído como un índice de base cero en la lista de 100,000 líneas que se leyeron, y envíe la línea correspondiente a la salida.
- Ingrese 100,000 líneas desde un archivo de texto, generando cada línea que contiene la secuencia de caracteres "fnord".
Para el primer programa, dependiendo del contenido del archivo de texto, la internación de cadenas puede generar casi un ahorro de memoria de 50,000: 1 (si la línea contenía 100,000 líneas de texto idénticas) o podría representar un desperdicio total (si las 100,000 líneas son diferente). En ausencia de internado de cadena, un archivo de entrada con 100,000 líneas idénticas causaría que existan 100,000 instancias en vivo de la misma cadena simultáneamente . Con el internado de cadenas, el número de instancias en vivo podría reducirse a dos. Por supuesto, no hay forma de que un compilador intente adivinar si el archivo de entrada puede contener 100,000 líneas idénticas, 100,000 líneas diferentes o algo intermedio.
Para el segundo programa, es poco probable que incluso una implementación ideal de internado de cadenas ofrezca muchos beneficios. Incluso si las 100.000 líneas del archivo de entrada fueran idénticas, el internado no podía ahorrar mucha memoria. El efecto de la pasantía no es evitar la creación de instancias de cadena redundantes, sino permitir que se identifiquen y descarten las instancias de cadena redundantes. Como cada línea se puede descartar una vez que se ha examinado y ya sea de salida o no, lo único que podría comprar interning sería la capacidad (teórica) de descartar instancias de cadena redundantes (muy) un poco antes de lo que sería posible.
Puede haber beneficios en algunos casos al almacenamiento en caché de ciertos resultados de cadena ''intermedios'', pero esa es una tarea que es mejor dejar al programador. Por ejemplo, tengo un programa que necesita convertir muchos bytes en cadenas hexadecimales de dos dígitos. Para facilitar eso, tengo una matriz de 255 cadenas que contienen los equivalentes de cadena de valores de 00 a FF. Sé que, en promedio, cada cadena de esa matriz se utilizará, como mínimo, cientos o miles de veces, por lo que almacenar esas cadenas en caché es una gran victoria. Por otro lado, las cadenas solo se pueden almacenar en caché porque sé lo que representan. Puedo saber que, para cualquier n
0-255, String.Format("{0:X2}",n)
siempre tendrá el mismo valor, pero no esperaría que un compilador lo sepa.
Los diseñadores de idiomas decidieron que el costo de internar cada valor de cadena intermedio no valía el costo de rendimiento. El internado de cadenas de recolección de basura requiere un único mapa débil global que puede convertirse en un cuello de botella cuando tiene un gran número de hilos.