views:

173

answers:

4

Hi!

If I want to concatenate a string N number of times, which method should i prefer?

Take this code as an example:

public static string Repeat(this string instance, int times)
{
        var result = string.Empty;

        for (int i = 0; i < times; i++)
            result += instance;

        return result;
}

This method may be invoked with "times" set to 5, or 5000. What method should I prefer to use?

string.Join? Stringbuilder? Just standard string.Concat?

A similar function is going to be implemented in a commercial library so I really need the "optimal" way to do this.

+5  A: 

Stringbuilder ofcourse. It is meant for fast string join operations, because it won't create new object each time you want to join a string.

For details see here.

Janis Veinbergs
+2  A: 

StringBuilder.

"result += result;"

creates a new string each and every time you do the assignment, and assign that new string to your variable, since strings are immutable.

Go with StringBuilder, definitely.

Erik A. Brandstadmoen
+6  A: 
    public static string Repeat(this string instance, int times)
    {
        if (times == 1 || string.IsNullOrEmpty(instance)) return instance;
        if (times == 0) return "";
        if (times < 0) throw new ArgumentOutOfRangeException("times");
        StringBuilder sb = new StringBuilder(instance.Length * times);
        for (int i = 0; i < times; i++)
            sb.Append(instance);
        return sb.ToString();
    }
Marc Gravell
Thanks, you have proven your point in a good way.
alexn
why not return string.Empty on line 4?
Vinko Vrsalovic
"" is string.Empty, as from MSDN : [The value of this field is the zero-length string, ""][1]. [1]: http://msdn.microsoft.com/en-us/library/system.string.empty.aspx
Janis Veinbergs
A: 

Never make an assumption that one method is faster than another -- you must alway measure the performance of both and then decide.

Surprisingly, for smaller numbers of iterations, just a standard string concatenation (result += string) is often faster than using a string builder.

If you know that the number of iterations will always be the same (e.g. it will always be 50 iterations), then I would suggest that you make some performance measurements using different methods.

If you really want to get clever, make performance measurements against number of iterations and you can find the 'crossover point' where one method is faster than another and hard-code that threshold into the method:

if(iterations < 30)
{
    CopyWithConcatenation();
}
else
{
    CopyWithStringBuilder();
}

The exact performance crossover point will depend on the specific detail of your code and you'll never be able to find out what they are without making performance measurements.

To complicate things a little more, StringBuilder has 'neater' memory management that string concatenation (which creates more temporary instances) so this might also have an impact on overall performance outside of your string loop (like the next time the Garbage Collector runs).

Let us know how you got on.

Dr Herbie