StringBuilder: hoe krijg ik de laatste string?

Iemand vertelde me dat het sneller is om strings samen te voegen met StringBuilder. Ik heb mijn code gewijzigd, maar ik zie geen eigenschappen of methoden om de definitieve build-string te krijgen.

Hoe kom ik aan de string?


Antwoord 1, autoriteit 100%

U kunt .ToString()gebruiken om de stringuit de StringBuilderte halen.


Antwoord 2, autoriteit 10%

Als je zegt “het is sneller om String samen te voegen met een String builder”, is dit alleen waar als je herhaaldelijk(ik herhaal – herhaaldelijk) aaneenvoegt naar hetzelfde voorwerp.

Als je gewoon 2 strings aaneenvoegt en iets doet met het resultaat onmiddellijk als een string, heeft het geen zin om StringBuilderte gebruiken.

Ik kwam zojuist Jon Skeet’s aardige beschrijving hiervan tegen: http://www. yoda.arachsys.com/csharp/stringbuilder.html

Als je StringBuildergebruikt en om de resulterende stringte krijgen, hoef je alleen maar ToString()aan te roepen (niet verwonderlijk).


Antwoord 3, autoriteit 8%

Als u de verwerking met StringBuilder hebt voltooid, gebruikt u de ToString-methode om het uiteindelijke resultaat te retourneren.

Van MSDN:

using System;
using System.Text;
public sealed class App 
{
    static void Main() 
    {
        // Create a StringBuilder that expects to hold 50 characters.
        // Initialize the StringBuilder with "ABC".
        StringBuilder sb = new StringBuilder("ABC", 50);
        // Append three characters (D, E, and F) to the end of the StringBuilder.
        sb.Append(new char[] { 'D', 'E', 'F' });
        // Append a format string to the end of the StringBuilder.
        sb.AppendFormat("GHI{0}{1}", 'J', 'k');
        // Display the number of characters in the StringBuilder and its string.
        Console.WriteLine("{0} chars: {1}", sb.Length, sb.ToString());
        // Insert a string at the beginning of the StringBuilder.
        sb.Insert(0, "Alphabet: ");
        // Replace all lowercase k's with uppercase K's.
        sb.Replace('k', 'K');
        // Display the number of characters in the StringBuilder and its string.
        Console.WriteLine("{0} chars: {1}", sb.Length, sb.ToString());
    }
}
// This code produces the following output.
//
// 11 chars: ABCDEFGHIJk
// 21 chars: Alphabet: ABCDEFGHIJK

Antwoord 4, autoriteit 2%

Ik wil gewoon weggooien dat het misschien niet per se sneller is, het zal zeker een betere geheugenvoetafdruk hebben. Dit komt omdat tekenreeksen onveranderlijk zijn in .NET en elke keer dat u een tekenreeks wijzigt, hebt u een nieuwe gemaakt.


Antwoord 5, autoriteit 2%

Over het feit dat het een sneller/beter geheugen is:

Ik heb dit probleem met Java onderzocht, ik neem aan dat .NET er net zo slim in zou zijn.

De implementatie voor String is behoorlijk indrukwekkend.

Het String-object volgt “length” en “shared” (onafhankelijk van de lengte van de array die de string bevat)

Dus zoiets als

String a = "abc" + "def" + "ghi";

kan worden geïmplementeerd (door de compiler/runtime) als:

- Verleng de array met "abc" met 6 extra spaties.
 - Kopieer def direct na abc
 - kopieer ghi in na def.
 - geef een pointer naar de string "abc" aan a
 - laat de lengte van abc op 3 staan, stel de lengte van a in op 9
 - stel de gedeelde vlag in beide in.

Omdat de meeste strings van korte duur zijn, zorgt dit in veel gevallen voor ZEER efficiënte code.
Het geval waarin het absoluut NIET efficiënt is, is wanneer je iets toevoegt aan een string binnen een lus, of wanneer je code er zo uitziet:

a = "abc";
a = a + "def";
a += "ghi";

In dit geval ben je veel beter af met een StringBuilder-constructie.

Mijn punt is dat je voorzichtig moet zijn wanneer je optimaliseert, tenzij je ABSOLUUT zeker weet dat je weet wat je doet, EN je absoluut zeker weet dat het nodig is, EN je test om ervoor te zorgen dat de geoptimaliseerde code een use case passeert, codeer het gewoon op de meest leesbare manier en probeer de compiler niet te slim af te zijn.

Ik heb 3 dagen verspild aan het knoeien met strings, het cachen/hergebruiken van string-builders en het testen van snelheid voordat ik naar de broncode van de string keek en ontdekte dat de compiler het al beter deed dan ik mogelijk zou kunnen voor mijn gebruik. Toen moest ik uitleggen hoe ik niet ECHT wist wat ik aan het doen was, ik dacht alleen dat ik het wist…


Antwoord 6

Het is niet sneller om samen te voegen. Zoals Smakel al aangaf, is het probleem de onveranderlijke string die een extra toewijzing en het opnieuw kopiëren van bestaande gegevens afdwingt.

“a”+”b”+”c” is niet sneller te doen met string builder, maar herhaalde concats met een tussenliggende string worden sneller en sneller naarmate het aantal concat’s groter wordt, zoals:

x = “een”; x+=”b”; x+=”c”; …

Other episodes