GOTCHA 5 String concatenation is expensive


GOTCHA #5 String concatenation is expensive

Objects of the String class in .NET are immutable. An immutable object is one that can't be modified once created. What is the effect of using the + operator (or & in VB.NET) to append a String? Each call creates a new String object. This can cause object-allocation overhead and put pressure on the garbage collector. What alternative do you have?

System.Text.StringBuilder provides a means for appending almost anything to a StringBuilder object. The benefits of using StringBuilder over String's +/& is illustrated in Example 1-7.

Example 1-7. Using StringBuilder versus +/ &

C# (StringAppend)

 using System; namespace StringAppendPerformance {     class Test     {         [STAThread]         static void Main(string[] args)         {             Console.Write("Enter number of strings to append:");             int count = Convert.ToInt32(Console.ReadLine());             string str = null;             int startTick = Environment.TickCount;             for (int i = 0; i < count; i++)             {                 str = str +".";             }             int endTick = Environment.TickCount;             double timeTakenByPlus =                 (endTick - startTick) / 1000.0;             System.Text.StringBuilder bldr =                 new System.Text.StringBuilder();             startTick = Environment.TickCount;             for (int i = 0; i < count; i++)             {                 bldr.Append(".");             }             endTick = Environment.TickCount;             double timeTakenByStringBuilder =                 (endTick - startTick) / 1000.0;             Console.Write("+ and StringBuilder took ");             Console.WriteLine("{0} and {1} seconds",                     timeTakenByPlus,                     timeTakenByStringBuilder);         }     } } 

VB.NET (StringAppend)

 Module Test     Sub Main()         Console.Write("Enter number of strings to append:")         Dim count As Integer = Convert.ToInt32(Console.ReadLine())         Dim str As String = Nothing         Dim startTick As Integer = Environment.TickCount         Dim i As Integer         For i = 0 To count - 1             str = str &"."         Next         Dim endTick As Integer = Environment.TickCount         Dim timeTakenByPlus As Double = _             (endTick - startTick) / 1000.0         Dim bldr As New System.Text.StringBuilder         startTick = Environment.TickCount         For i = 0 To count - 1             bldr.Append(".")         Next         endTick = Environment.TickCount         Dim timeTakenByStringBuilder As Double = _             (endTick - startTick) / 1000.0         Console.Write("& and StringBuilder took ")         Console.WriteLine("{0} and {1} seconds", _           timeTakenByPlus, _           timeTakenByStringBuilder)     End Sub End Module 

Executing the above program with different values for the number of strings to append produces the results shown in Table 1-3.

Table 1-3. Performance, in seconds, of concatenation versus StringBuilder

# of appends

+

StringBuilder

10

0.000

0.00

100

0.000

0.00

1,000

0.000

0.00

2,500

0.000

0.00

5,000

0.020

0.00

7,500

0.050

0.00

10,000

0.090

0.00

15,000

0.250

0.00

25,000

1.052

0.00

35,000

2.373

0.00

50,000

5.699

0.00

65,000

10.625

0.00

75,000

14.831

0.01

85,000

19.418

0.01

100,000

27.159

0.01

150,000

65.374

0.01

250,000

209.221

0.02

350,000

441.615

0.02

500,000

910.129

0.04

650,000

1521.708

0.06

750,000

1999.305

0.06

850,000

2576.575

0.06

1,000,000

3562.933

0.07


The timing using the ampersand (&) in VB.NET is comparable to that of the concatenation operator (+) in C#. As the above example shows, StringBuilder is much less expensive than using + (or &) to build up a string. Furthermore, if you use StringBuilder you create fewer objects than using the +/&. This can be seen using the CLR Profiler (see "On the Web" in the Appendix). For instance, if you run 10,000 appends, the number of String instances created using +/& is 10,039. However, if you replace the +/& with StringBuilder.Append(), the number of String instances drops to 51.

For an interactive client application with a few concatenations here and there, it may not make a big difference. For a server-side application, however, the difference may be significant and the use of StringBuilder is probably better. It must be noted that the instance members of a StringBuilder are not thread-safe, so you may have to take care to appropriately synchronize access to them.

IN A NUTSHELL

If you find yourself appending a large number of strings, you will improve performance by using StringBuilder.Append() instead of the concatenation operators (+/&). This is especially important in server-side/backend applications.

SEE ALSO

Gotcha #9, "Typeless ArrayList isn't type-safe" and Gotcha #21, "Default performance of Data.ReadXML is poor."



    .NET Gotachas
    .NET Gotachas
    ISBN: N/A
    EAN: N/A
    Year: 2005
    Pages: 126

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net