Czemu konkatenacja stringów jest wolniejsza niż użycie stringbuildera?

By | 1 maja 2018

O tym że StringBuilder append jest dużo szybszy niż zwykła konkatenacja w języku C# wiedziałem, jednak nie miałem pojęcia jaka jest skala tych różnic i co za tym stoi. Nie zawsze mam czas na to żeby sprawdzać dlaczego coś działa tak a nie inaczej, ale tym razem miałem więc przygotowałem proste omówienie tego zjawiska 😉

String w języku C# (JAVA również) są niezmienne. Oznacza to, że metody działające na łańcuchach nie mogą nigdy zmienić wartości ciągu. Łączenie ciągów za pomocą += działa poprzez przydzielanie pamięci dla zupełnie nowego ciągu, który jest połączeniem dwóch poprzednich. Każda nowa konkatenacja wymaga zbudowania całkowicie nowego obiektu String a co za tym idzie zaalokować część pamięci w której będzie się nowy obiekt znajdował. To zajmuję czas i zwiększa użycie pamięci.

Z drugiej strony StringBuilder wstępnie alokuje bufor, a dodając do niego łańcuchy, nie trzeba go ponownie przypisywać (zakładając, że początkowy bufor jest wystarczająco duży). Co zwiększa wydajność i znacznie mniej obciąża pamięć.

Czy to oznacza że StringBuilder jest zawsze najlepszym rozwiązaniem? No właśnie nie zawsze, ponieważ w przypadku niedużych ciągów znaków ilość pamięci alokowanej i narzut wydajnościowy przewyższa proste użycie Stringa, a kod staje się nieco mniej czytelny niż proste wywołanie return string1 + string2;

Kod porównujący wydajność obu sposobów

public static void ZwyklaKonkatenacja()
{
	var tekst = "";
	Stopwatch test1 = Stopwatch.StartNew();
	test1.Start();
	for (int i = 0; i < 100000; i++)
	{
		tekst += "Y";
	}
	test1.Stop();
	Console.WriteLine("Konkatenacja " + test1.ElapsedMilliseconds + " ms");
}

public static void KonkatenacjaStringBuilder()
{
	var sb = new System.Text.StringBuilder();
	Stopwatch test2 = Stopwatch.StartNew();
	test2.Start();
	for (int i = 0; i < 100000; i++)
	{
		sb.Append("Y");
	}
	test2.Stop();
	Console.WriteLine("StringBuilder " + test2.ElapsedMilliseconds + " ms");
}

Wyniki szybkości działania funkcji

Wpis został zainspirowany przez kolegę z pracy, który ostatnio optymalizuje co tylko się da. Zaskoczył mnie, ponieważ wiedziałem że różnica jest, ale nie spodziewałem się że jest aż tak ogromna. Tak więc wielkie podziękowania.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *