Question

Je application de test créé pour tester, est StringBuilder copier des données à une autre instance et développer ce tampon lorsque sa longueur est plus que la capacité actuelle et vérifier dans ildasm.exe mais il semble identique.

Comment vérifier StringBuilder copiera ses données dans une nouvelle instance et développer la mémoire tampon par la limite spécifiée?

Était-ce utile?

La solution

Si vous voulez vérifier comment StringBuilder est mis en œuvre, lancez simplement réflecteur et regarder. La mise en œuvre de StringBuilder.Append(string) est la suivante

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;
}

Regardez la section avec NeedsAllocation, GetNewString et ainsi de suite pour trouver ce que vous cherchez.

Autres conseils

Capacité représente la mémoire contiguë alloué au StringBuilder. La capacité peut être> = longueur de la chaîne. Lorsque plusieurs données sont ajoutées à la StringBuilder à la capacité, StringBuilder augmente automatiquement la capacité. Etant donné que la capacité a dépassé (qui est la mémoire contiguë est rempli et pas plus de place tampon est disponible), une zone tampon plus grande est attribuée et les données sont copiées depuis la mémoire d'origine à cette nouvelle zone.

Il ne copie pas de données à la nouvelle « instance », mais à nouveau « emplacement mémoire ». L'instance reste la même, mais pointe vers le nouvel emplacement mémoire.

Modifier Pour votre information: capacité par défaut de StringBuilder si non spécifié lors de la création est 16

Si vous voulez voir les emplacements de mémoire pour StringBuilder vous pouvez déboguer vos applications et vérifiez la mémoire à l'aide de débogage> de Windows> Mémoire. Vous pouvez voir l'adresse de chaque octet stocké dans votre StringBuilder lorsque Append stmt fonctionne.

Si vous avez besoin pour obtenir les emplacements ce lien pourrait aider.

Non pas que nous sommes vraiment tester que les travaux de StringBuilder, parce qu'il fait, mais pour votre propre plaisir, vous pouvez toujours écrire un test unitaire.

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.

Sans surprise, elle passe, et la sortie suivante est donnée.

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

La façon dont le StringBuilder augmente son tampon en cas de besoin est quelque chose qui est pris en charge par le code interne du StringBuilder; il ne sera pas affiché dans le code IL de votre application; le compilateur ne peut pas savoir comment grandes chaînes StringBuilder dans une certaine méthode contiendra, car cela peut varier de temps à autre.

Cependant, lorsque le StringBuilder fait augmenter sa mémoire tampon, il ne résultera pas en une nouvelle instance de StringBuilder. Il peut en résulter, il copie la représentation interne de la chaîne qu'il détient à une nouvelle instance (je ne connais pas assez le fonctionnement interne de la classe de dire exactement ce qui se passe).

Vous pouvez utiliser réflecteur pour voir à peu près comment fonctionne StringBuilder.

Voir méthode

StringBuilder Append(string value)

3,5 pour .NET logique est la suivante:. Si la longueur de la mémoire tampon ne suffit pas pour la nouvelle chaîne de caractères, créer un nouveau tampon de longueur égale à Max (oldSize * 2, RequiredSize)

En d'autres termes, StringBuffer essaie de doubler le tampon et si cela ne suffit pas fait alors la taille de la mémoire tampon juste assez pour s'adapter à la nouvelle chaîne.

Référence à l'ancien tampon se retire et le vieux tampon se récupéré avec la prochaine collecte des ordures.

 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
        }
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top