C# – String.Concat vs String.Join

C

I had a quick Google search for a comparison between string.concat and string.join, but I couldn’t find anything.

Say you want to construct the sentence “The quick brown fox jumps over the lazy dog”

This is comprised of 9 words, 8 spaces.

Using string.concat:

public void CreateSentanceUsingStringConcat()
{
    string space = " ";
    string the = "the";
    string quick = "quick";
    string brown = "brown";
    string fox = "fox";
    string jumps = "jumps";
    string over = "over";
    string lazy = "lazy";
    string dog = "dog";

    var result = string.Concat(the, space, quick, space, brown, space, fox, space, jumps, space, over, space, the, space, lazy, space, dog);
}

Using string.join

public void CreateSentanceUsingStringJoin()
{
    var result = string.Join(space, the, quick, brown, fox, jumps, over, the, lazy, dog);
}

With String.concat, we must explicitly add the separator (in our case, space) between each string.

String.join however, allows us to specify the separator as the first parameter.

Performance

I wrote a small benchmark test on the two (see bottom of this post for code)

We can see string.join consistently performs better

string concat vs string join

Benchmark Code:

Note – This is available on GitHub – http://github.com/alexjamesbrown/StringConcatVsStringJoin

class Program
{
    //string.concat or string.join a million times to get a better reading
    const int numberOfTimesToRun = 1000000;

    const string space = " ";
    const string the = "the";
    const string quick = "quick";
    const string brown = "brown";
    const string fox = "fox";
    const string jumps = "jumps";
    const string over = "over";
    const string lazy = "lazy";
    const string dog = "dog";

    static void Main()
    {
        for (var i = 1; i <= 5; i++)
        {
            Console.WriteLine("Pass #" + i);
            Go();
            Console.WriteLine();
        }

        Console.Read();
    }

    private static void Go()
    {
        var concatStopWatch = Stopwatch.StartNew();

        for (var i = 0; i < numberOfTimesToRun; i++)
            string.Concat(the, space, quick, space, brown, space, fox, space, jumps, space, over, space, the, space, lazy, space, dog);

        concatStopWatch.Stop();

        var joinStopWatch = Stopwatch.StartNew();
        for (var i = 0; i < numberOfTimesToRun; i++)
            string.Join(space, the, quick, brown, fox, jumps, over, the, lazy, dog);

        joinStopWatch.Stop();

        Console.WriteLine("string.join - {0}", joinStopWatch.ElapsedMilliseconds);
        Console.WriteLine("string.concat- {0}", concatStopWatch.ElapsedMilliseconds);
    }
}

 


Update – StringBuilder.Append

In the comments, Dejan Stojanović put together a similar test using StringBuilder.Append – with similar, and sometimes slightly better results!

With stringbuilder.append

See this commit for the update

<span class="dsq-postid" data-dsqidentifier="623 http://www.alexjamesbrown.com/uncategorized/c-string-concat-vs-string-join/">14 comments</span>

  • You have switched your captions/timers in your Console.WriteLine. s1 is the concat timer, s2 is the join timer. If you use names like joinTimer and concatTimer this would be obvious

    • Sorry, I totally missed this comment (for 2 years it seems)
      Switching to Disqus and Tim’s comment below has alerted me to it!

      I’ll fix this!

  • Andrew’s comment is two years old but the code is still incorrect. So actually string.Join is faster.

  • I just saw this test and wanted to add one more methods and that is StringBuilder. I was amazed that StringBuilder.Append worked even faster than String.Join.

    As far as I could see in most of the articles on internet, StringBuilder is described as the slowest one, but in this test it had the best score.

    The following is test code and attached are results screenshot

    var stringbuilderStopWatch = Stopwatch.StartNew();

    for (var i = 0; i < numberOfTimesToRun; i++)

    new StringBuilder().Append(space).Append(the).Append(quick).Append(brown).Append(fox).Append(jumps).Append(over).Append(the).Append(lazy).Append(dog);

    stringbuilderStopWatch.Stop();