Feature Request: Add String.Concat to performance warnings C# .NET 4.5
Hello,
Would it be possible to add a warning regarding String.Concat in .NET 4.5?
There is an issue reported on Microsoft's Connect website: https://connect.microsoft.com/VisualStudio/feedback/details/780770/string-concat-slow-in-net-4-5#details
Looking at the results, it appears that String.Concat is up to 200 times slower than similar operations. Microsoft have given a workaround, but not a solution.
Given the large difference in the results (if it were only a few ms I wouldn't ask), I think it would be important to tell people that potentially they could kill the performance of their application.
Please sign in to leave a comment.
Hi,
Thanks for the suggestion - I've logged it here: http://youtrack.jetbrains.com/issue/RSRP-373571.
You're weelcome to vote for it and monitor its status there.
Thanks again!
Thanks for that Alex!
Didn't realise you had youtrack, obviously wasn't looking hard enough! ;)
You do realise that the code in your article doesn't produce the same string in 3.5 as it does in 4.5? In 4.5, you'll get the same 10000 character string back; in 3.5, you'll just get the result of calling ToString on the list you've passed in.
The performance of String.Concat still sucks, but it's no worse in 4.5 than it was in previous versions.
Did you try it? Running the following in 3.5:
produces the following output:
The code is calling the Concat(Object) overload, not the Concat(Object[]) overload.
The workaround that Microsoft suggested suffers from the same problem: the string you get back isn't what you were expecting.
Changing your code so that it works as expected in 3.5 actually shows significantly worse performance than in 4.5, possibly due to the fact that you have to convert the Char array to a String array before you can call the methods.
You'll also find that your StringBuilder method doesn't work as expected in 4.5; there is no Append overload which accepts an IEnumerable<Char>, so only the Char array test produces the correct output.
OK, so you've edited your post and completely changed what you said, which now makes my other response look odd.
The only place I can see in your article which mentions this problem is a comment by "Ketsuekiame", which seems to have been ignored.
Running your code in 3.5 produces the wrong output. The only case where it would produce the correct output in 3.5 with better performance than 4.5 is if you pass a single String to the Concat method; 3.5 would call Concat(Object), whereas 4.5 would call Concat<Char>(IEnumerable<Char>). In every other case, the 3.5 code will not work as expected.
The performance might suck, but I'll take slow code which produces the correct output over fast code which produces garbage any day!
Thank you for pointing out the problem with the testing. :)
It seems String.Concat in IEnumerable<Char> is quick, possibly because it has a direct route turn it into a String?
Otherwise yes, String.Concat performance is diabolical :)
The reason your IEnumerable<Char> test works is because the variable already contains a String:
The AsEnumerable method simply returns the input parameter, which means that numCharString has a compile-time type of IEnumerable<Char>, but a run-time type of String. When you pass that to the String.Concat(Object) method, it calls ToString on the parameter. Calling ToString on a String returns the same String, so this appears to work.
If you change your code to use an IEnumerable<Char> which isn't a String, you'll see the same problem as the other tests:
Yes, that's what I meant by a direct route, sorry sometimes I'm not clear with language.