Link: StringBuilder i ciekawostka o implementacji wewnętrznej w .NET 4.0

Implementacja wewnętrzna StringBuilder uległa zmianie w .NET 4.0 (teraz używana jest lista jednokierunkowa zamiast tablicy) i z tego względu ustawienie właściwości Length na zero może spowodować znaczącą utratę wydajności. Polecam przeczytanie tego wpisu:

http://blogs.msdn.com/b/jankrivanek/archive/2012/11/30/stringbuilder-performance-issues-in-net-4-0-and-4-5.aspx

One thought on “Link: StringBuilder i ciekawostka o implementacji wewnętrznej w .NET 4.0”

  1. > teraz używana jest lista jednokierunkowa zamiast tablicy

    Niedokładnie – StringBuilder używa i tablicy znaków i listy jednokierunkowej. Kolejny obiekt StringBuilder (jako kontener na dane) jest tworzony kiedy w bieżącym buforze dane się już nie mieszczą – dopóki mamy miejsce w bierzącym buforze (czyli w tablicy znaków) jest on wypełniany. Długość kolejnego bufora (który będziemy tworzony kiedy zabraknie miejsca w bierzącym) jest liczona tak:

    int num = Math.Max(minBlockCharCount, Math.Min(this.Length, 0x1f40));

    Czyli bierzemy Min’a z bieżącej ilości buforowanych danych i 8000, a następnie Max’a z poprzedniej wartości i ilości znaków do dodania.

    Oto cały kod funkcji powiększającej bufor na dane:

    private void ExpandByABlock(int minBlockCharCount)
    {
    if ((minBlockCharCount + this.Length) > this.m_MaxCapacity)
    {
    throw new ArgumentOutOfRangeException(“requiredLength”, Environment.GetResourceString(“ArgumentOutOfRange_SmallCapacity”));
    }
    int num = Math.Max(minBlockCharCount, Math.Min(this.Length, 0x1f40));
    this.m_ChunkPrevious = new StringBuilder(this);
    this.m_ChunkOffset += this.m_ChunkLength;
    this.m_ChunkLength = 0;
    if ((this.m_ChunkOffset + num) < num)
    {
    this.m_ChunkChars = null;
    throw new OutOfMemoryException();
    }
    this.m_ChunkChars = new char[num];
    }

    Więc jeśli chodzi o operację Append to nie wygląda to tak źle.

Leave a Reply

Your email address will not be published.