Pregunta

Tengo aplicación de prueba creados para probar, es StringBuilder copiar datos a otra instancia y hacerlo crecer búfer cuando su longitud es mayor que la capacidad actual y verificar en ildasm.exe pero parece idéntica.

Cómo comprobar StringBuilder copiará sus datos en nueva instancia y hacer crecer la memoria intermedia por el límite especificado?

¿Fue útil?

Solución

Si desea inspeccionar cómo se implementa StringBuilder, solo use el reflector y mirarlo. La aplicación de StringBuilder.Append(string) es el siguiente

public StringBuilder Append(string value)
{
   if (value != null)
   {
      string stringValue = this.m_StringValue;
      IntPtr currentThread = Thread.InternalGetCurrentThread();
      if (this.m_currentThread != currentThread)
      {
         stringValue = string.GetStringForStringBuilder(stringValue, stringValue.Capacity);
      }
      int length = stringValue.Length;
      int requiredLength = length + value.Length;
      if (this.NeedsAllocation(stringValue, requiredLength))
      {
         string newString = this.GetNewString(stringValue, requiredLength);
         newString.AppendInPlace(value, length);
         this.ReplaceString(currentThread, newString);
      }
      else
      {
         stringValue.AppendInPlace(value, length);
         this.ReplaceString(currentThread, stringValue);
      }
   }
   return this;
}

Mire la sección con NeedsAllocation, GetNewString y así sucesivamente para encontrar lo que estás buscando.

Otros consejos

Capacidad representa la memoria contigua asignado al StringBuilder. La capacidad puede ser> = longitud de la cadena. Cuando más datos se añaden a la StringBuilder que la capacidad, StringBuilder aumenta automáticamente la capacidad. Dado que se ha excedido la capacidad (es decir memoria contigua está lleno y no hay más espacio tampón está disponible), una zona de búfer mayor se asigna y se copian los datos de la memoria original a esta nueva área.

No copia los datos a la nueva 'instancia', pero a nueva 'posición de memoria'. La instancia sigue siendo el mismo, pero apunta a la nueva ubicación de la memoria.

Editar FYI: la capacidad predeterminada de StringBuilder si no se especifica durante la creación es 16

Si quieres ver las posiciones de memoria para StringBuilder entonces se puede depurar sus aplicaciones y comprobar el uso de memoria de depuración> Windows> Memoria. En realidad se puede ver la dirección de todas y cada byte almacenado en su StringBuilder cuando Anexar stmt funciona.

Si usted necesita para obtener las ubicaciones este enlace podría ayudar.

No es que realmente estamos probando que las obras de StringBuilder, porque lo hace, pero para su propio disfrute siempre se puede escribir una prueba unitaria.

StringBuilder sb = new StringBuilder(10);
Console.WriteLine("Capacity = " + sb.Capacity + " Length = " + sb.Length 
      + " MaxCapacity = " + sb.MaxCapacity);
sb.Append("1234567890");
sb.Append("1234567890");
sb.Append("1234567890");
Console.WriteLine("Capacity = " + sb.Capacity + " Length = " + sb.Length 
      + " MaxCapacity = " + sb.MaxCapacity);
Assert.AreEqual("123456789012345678901234567890"
      , sb.ToString()); // NUnit assert.

Como era de esperar, se pasa, y se da la siguiente salida.

    Capacity = 10 Length = 0 MaxCapacity = 2147483647
    Capacity = 40 Length = 30 MaxCapacity = 2147483647

La forma en que el StringBuilder aumenta su memoria intermedia cuando sea necesario es algo que está atendido por el código interno de la StringBuilder; no se mostrará en el código IL de su aplicación; el compilador no puede saber cómo las cadenas grandes de la StringBuilder en un determinado método contendrá, ya que puede variar de vez en cuando.

Sin embargo, cuando el StringBuilder hace aumentar su memoria intermedia, no va a dar lugar a una nueva instancia de StringBuilder. Puede dar lugar a que la copia de la representación interna de la cadena que se lleva a cabo a una nueva instancia (no sé lo suficiente sobre el funcionamiento interno de la clase a decir exactamente lo que sucede).

Puede utilizar el reflector para ver más o menos cómo funciona StringBuilder.

Vea método

StringBuilder Append(string value)

For .Net 3,5 lógica es la siguiente:. Si la longitud de memoria intermedia no es suficiente para la nueva cadena, crear nuevos tampón con longitud igual a Max (oldSize * 2, RequiredSize)

En otras palabras, StringBuffer trata de duplicar la memoria intermedia y si eso no es suficiente, entonces hace tamaño del búfer lo suficiente para que la nueva cadena.

La referencia a la antigua memoria intermedia se elimina y el búfer de edad se recuperó con la próxima recolección de basura.

 class Program
    {
        static void Main()
        {
            StringBuilder sb = new StringBuilder();
            Console.WriteLine(sb.Capacity); //16

            for (int i = 0; i < 50; i++) 
                sb.Append(i + ",");

            Console.WriteLine(sb.Capacity); //256

            sb = new StringBuilder();
            Console.WriteLine(sb.Capacity); //16
        }
    }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top