Szukaj…


Czym jest StringBuilder i kiedy go używać

StringBuilder reprezentuje serię znaków, które w przeciwieństwie do normalnego łańcucha, można modyfikować. Często istnieje potrzeba modyfikacji napisów, które już stworzyliśmy, ale standardowy obiekt napisów nie jest modyfikowalny. Oznacza to, że za każdym razem, gdy łańcuch jest modyfikowany, należy utworzyć nowy obiekt łańcucha, skopiować go, a następnie ponownie przypisać.

string myString = "Apples";
mystring += " are my favorite fruit";

W powyższym przykładzie myString początkowo ma tylko wartość "Apples" . Jednak, gdy konkatenujemy „są moimi ulubionymi owocami”, klasa strunowa musi zrobić wewnętrznie:

  • Tworzymy nową tablicę znaków równą długości myString i nowego ciągu, który myString .
  • Kopiowanie wszystkich znaków myString na początek naszej nowej tablicy i kopiowanie nowego łańcucha na koniec tablicy.
  • Utwórz nowy obiekt ciągu w pamięci i myString go do myString .

W przypadku pojedynczego połączenia jest to stosunkowo trywialne. Co jednak, jeśli trzeba wykonać wiele operacji dołączania, powiedzmy, w pętli?

String myString = "";
for (int i = 0; i < 10000; i++)
    myString += " "; // puts 10,000 spaces into our string

Ze względu na powtarzające się kopiowanie i tworzenie obiektów spowoduje to znaczne obniżenie wydajności naszego programu. Możemy tego uniknąć, zamiast tego używając StringBuilder .

StringBuilder myStringBuilder = new StringBuilder();    
for (int i = 0; i < 10000; i++)
    myStringBuilder.Append(' ');

Teraz, gdy uruchomiona zostanie ta sama pętla, wydajność i szybkość czasu wykonywania programu będą znacznie szybsze niż przy użyciu zwykłego ciągu. Aby zmienić StringBuilder w normalny ciąg, możemy po prostu wywołać metodę ToString() StringBuilder .


Nie jest to jednak jedyna optymalizacja, jaką posiada StringBuilder . W celu dalszej optymalizacji funkcji możemy skorzystać z innych właściwości, które pomagają poprawić wydajność.

StringBuilder sb = new StringBuilder(10000); // initializes the capacity to 10000

Jeśli wiemy z góry, jak długo powinien trwać nasz StringBuilder , możemy z wyprzedzeniem określić jego rozmiar, co uniemożliwi mu zmianę rozmiaru tablicy znaków, którą ma wewnętrznie.

sb.Append('k', 2000);

Chociaż użycie StringBuilder do dodawania jest znacznie szybsze niż ciąg, może działać jeszcze szybciej, jeśli trzeba dodać tylko jeden znak wiele razy.

Po zakończeniu budowania łańcucha możesz użyć metody ToString() w StringBuilder aby przekonwertować go na string podstawowy. Jest to często konieczne, ponieważ klasa StringBuilder nie dziedziczy po string .

Na przykład, oto jak możesz użyć StringBuilder do utworzenia string :

string RepeatCharacterTimes(char character, int times)
{
    StringBuilder builder = new StringBuilder("");
    for (int counter = 0; counter < times; counter++)
    {
        //Append one instance of the character to the StringBuilder.
        builder.Append(character);
    }
    //Convert the result to string and return it.
    return builder.ToString();
}

Podsumowując, StringBuilder powinien być używany zamiast łańcucha, gdy trzeba wprowadzić wiele modyfikacji łańcucha, mając na uwadze wydajność.

Użyj StringBuilder, aby utworzyć ciąg znaków z dużej liczby rekordów

public string GetCustomerNamesCsv()
{
    List<CustomerData> customerDataRecords = GetCustomerData(); // Returns a large number of records, say, 10000+

    StringBuilder customerNamesCsv = new StringBuilder();
    foreach (CustomerData record in customerDataRecords)
    {
       customerNamesCsv
           .Append(record.LastName)
           .Append(',')
           .Append(record.FirstName)
           .Append(Environment.NewLine);
    }

    return customerNamesCsv.ToString();
}


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow