2011-09-25 10 views
5

Cuando tengo un StringBuilder vacío con una capacidad de 5 y escribo "¡Hola, mundo!" Para ello, ¿el estándar C# especifica la nueva capacidad del StringBuilder? Tengo una vaga memoria de que es el doble de la longitud de la nueva cuerda (para evitar cambiar la capacidad con cada nueva cuerda anexada).¿Cómo cambia la capacidad de StringBuilder?

+4

esto no se especifica en cualquier punto de vista, es sólo un detalle de implementación – BrokenGlass

+0

StringBuilder no es parte del lenguaje C#. Es parte de las bibliotecas .net. –

+0

posible duplicado de [¿Cómo decide StringBuilder qué tan grande debe ser su capacidad?] (Http://stackoverflow.com/questions/4495855/how-does-the-stringbuilder-decide-how-large-its-capacity-should -be) – bzlm

Respuesta

15

Depende de qué versión de .NET estás hablando. Antes de .NET 4, StringBuilder utilizaba el standard .NET strategy, duplicando la capacidad del búfer interno cada vez que necesita ampliarse.

StringBuilder fue completamente reescrito para .NET 4, ahora usando ropes. La extensión de la asignación ahora se realiza al agregar otra pieza de cuerda de hasta 8000 caracteres. No es tan eficiente como la estrategia anterior, pero evita problemas con grandes almacenamientos intermedios que obstruyen el gran montón de objetos. El código fuente está disponible en la Fuente de referencia si desea ver más de cerca.

+0

Nos molestó cuando actualizamos nuestro producto de .Net 3.5 a .Net 4.5. Estábamos utilizando un objeto generador de cadenas como parámetro para una llamada API nativa a través de interoperabilidad. Resultó en un problema de desbordamiento del búfer que causó el bloqueo del proceso. La memoria del montón se corrompía cuando la API nativa devolvía cadenas largas. Comenzamos a proporcionar capacidad explícita en el constructor para que el búfer pueda ocuparse de cadenas largas. Sorprendentemente, también debería haber estado rompiendo antes para cadenas largas, pero nunca se informó. ¿Hay algún truco en .Net 3.5 cuando usamos el generador de cadenas como buffer para API nativas? – RBT

+0

Eso corrompe el montón de GC en la versión de tiempo de ejecución. Tal corrupción no se detecta necesariamente, tienes que tener suerte. Claro, usted tiende a tener más suerte en .NET 4 –

5

El estándar C# no especificará el comportamiento de una clase de biblioteca BCL ya que no tiene nada que ver con la especificación del lenguaje.

Por lo que yo sé el comportamiento real no se define en ninguna especificación y es específico de la implementación.

yo sepa, la aplicación MS se duplicará la capacidad una vez que se ha alcanzado la capacidad actual.

Ver this y this preguntas anteriores de SO.


Actualización:

Esto ha cambiado en .NET 4.0. como se describe por Hans en his answer. Ahora se usa ropes, agregando 8000 caracteres adicionales a la vez.

MSDN, sin embargo es muy cuidadoso en señalar que el comportamiento real es aplicación específica:

El StringBuilder asigna dinámicamente más espacio cuando sea necesario y aumenta la capacidad en consecuencia. Por razones de rendimiento, un StringBuilder podría asignar más memoria de la necesaria. La cantidad de memoria asignada es específica de la implementación.

+2

Ya no usamos la estrategia de doble cuando está completa. –

+1

@Eric - Gracias por corregirme. Eso y la respuesta de Hans me dieron más detalles. – Oded

-1

Nueva StringBuilder (.NET 4.5 o superior) asigna un buffer interno m_ChunkChars solicitada por el parámetro de capacidad:

public StringBuilder(int capacity) { ... m_ChunkChars = new char[capacity]; ... }

Por lo tanto, si la capacidad es menor que 40K caracteres que va en el Objeto Pequeño montón. Sin embargo (al contrario de la creencia popular), StringBuilder todavía asignará en el montón de objetos grandes si, más adelante, que llamamos sb.Append(...some string larger than 40K chars...); Una posible solución puede ser encontrado aquí: https://github.com/amikunov/Large-Object-Heap-Fix-For-.NET-String-Builder

+1

Esto no tiene nada que ver con lo que la pregunta está haciendo. – Servy

Cuestiones relacionadas