stringbuilder versus string concat

In my project I am looping across a dataview result.

 string html =string.empty;
 DataView dV = data.DefaultView;
 for(int i=0;i< dV.Count;i++)
 {
     DataRowView rv = dV[i];
     html += rv.Row["X"].Tostring();
 }

Number of rows in dV will alway be 3 or 4.

Is it better to use the string concat += opearator or StringBuilder for this case and why?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

I would use StringBuilder here, just because it describes what you’re doing.

For a simple concatenation of 3 or 4 strings, it probably won’t make any significant difference, and string concatenation may even be slightly faster – but if you’re wrong and there are lots of rows, StringBuilder will start getting much more efficient, and it’s always more descriptive of what you’re doing.

Alternatively, use something like:

string html = string.Join("", dv.Cast<DataRowView>()
                                .Select(rv => rv.Row["X"]));

Note that you don’t have any sort of separator between the strings at the moment. Are you sure that’s what you want? (Also note that your code doesn’t make a lot of sense at the moment – you’re not using i in the loop. Why?)

I have an article about string concatenation which goes into more detail about why it’s worth using StringBuilder and when.

EDIT: For those who doubt that string concatenation can be faster, here’s a test – with deliberately “nasty” data, but just to prove it’s possible:

using System;
using System.Diagnostics;
using System.Text;

class Test
{
    static readonly string[] Bits = { 
        "small string",
        "string which is a bit longer",
        "stirng which is longer again to force yet another copy with any luck"
    };

    static readonly int ExpectedLength = string.Join("", Bits).Length;

    static void Main()        
    {
        Time(StringBuilderTest);
        Time(ConcatenateTest);
    }

    static void Time(Action action)
    {
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
        // Make sure it's JITted
        action();
        Stopwatch sw = Stopwatch.StartNew();
        for (int i = 0; i < 10000000; i++)
        {
            action();
        }
        sw.Stop();
        Console.WriteLine("{0}: {1} millis", action.Method.Name,
                          (long) sw.Elapsed.TotalMilliseconds);
    }

    static void ConcatenateTest()
    {
        string x = "";
        foreach (string bit in Bits)
        {
            x += bit;
        }
        // Force a validation to prevent dodgy optimizations
        if (x.Length != ExpectedLength)
        {
            throw new Exception("Eek!");
        }
    }

    static void StringBuilderTest()
    {
        StringBuilder builder = new StringBuilder();
        foreach (string bit in Bits)
        {
            builder.Append(bit);
        }
        string x = builder.ToString();
        // Force a validation to prevent dodgy optimizations
        if (x.Length != ExpectedLength)
        {
            throw new Exception("Eek!");
        }
    }
}

Results on my machine (compiled with /o+ /debug-):
StringBuilderTest: 2245 millis
ConcatenateTest: 989 millis

I’ve run this several times, including reversing the order of the tests, and the results are consistent.

Method 2

StringBuilder is recommended.. why dont you do an analysis for yourself and then decide what is the best for you..

var stopWatch=new StopWatch();
stopWatch.Start();
string html =string.empty;
        DataView dV = data.DefaultView;
        for(int i=0;i< dV.Count;i++)
        {
           html += dV.Row["X"].Tostring();
        } 
stopWatch.Stop();
Console.Write(stopWatch.EllapsedMilliseconds());

var stopWatch=new StopWatch();
stopWatch.Start();
string html =new StringBuilder();
        DataView dV = data.DefaultView;
        for(int i=0;i< dV.Count;i++)
        {
           html.Append(dV.Row["X"].ToString());
        } 
var finalHtml=html.ToString();
stopWatch.Stop();
Console.Write(stopWatch.EllapsedMilliseconds());

Method 3

From the Documentation:

The String class is preferable for a concatenation operation if a
fixed number of String objects are concatenated. In that case, the
individual concatenation operations might even be combined into a
single operation by the compiler.

A StringBuilder object is preferable for a concatenation operation if
an arbitrary number of strings are concatenated; for example, if a
loop concatenates a random number of strings of user input.

So in your case i would say the String is better.

EDIT:

This is a no end disscussion, anyway i would recommend you to check how many opaeration do you have in average and test the performance for each one of them to compare results.

Check this nice link regarding this issue including some performance test code.

Method 4

StringBuilder for sure. String are immutable remember !

EDIT: For 3-4 rows, concatenation will be a preferred choice as Jon Skeet has said in his answer

Method 5

StringBuilder is recommended. It is mutable. It should place much less stress on the memory allocator 🙂

A string instance is immutable. You cannot change it after it was
created.
Any operation that appears to change the string instead returns a new instance.

Method 6

stringbuilder is what you are looking for. In general, if there is a function for some job try to utilize it instead of writing some procedure which does pretty much the same job.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x