C# string performance – Tips and Tricks
After many years of development, C# has become an extremely popular and easy-to-use managed language. Anyone can learn C#, and that gives rise to plenty of harmful habits that hurt the performance of programs written in C#. One search and you get dozens of different results, with different advice, along with different benchmark code — tangled enough to leave you confused.
1. Why is that?
Very simple: because those benchmark snippets, although written in the same C# language, run on different .NET Framework versions. You don’t have to guess to know that the later the version, the more efficiently the compiler works and the better the performance of the code you write. It’s even smart enough to spot ugly coding habits and compile the most efficient code for you anyway.
That said, overall there are some problems that “endure through time” and that you may run into when writing a C# app
This post focuses mainly on C# 6.0, which is used for Windows 10 UWP apps
The reference project used in this post: https://github.com/huntertran/00-Multi-Utilities/tree/master/09%20-%20Test%20Peformance/TestPerformance
2. The problems
String is a complex type in C#. Where in SQL you declare varchar or nvarchar with a fixed length, in C# a string can be enormously long. So the compiler has a hard time handling these string variables.
2.1. Mistake 1: concatenating strings
string msg = "Hello, ";
msg += "Tuan Tran";
msg += ". Today is ";
msg += System.DateTime.Now.ToString();
The code above is perfectly ordinary, as ordinary as sugar and canned milk. However, here is what the compiler sees
string msg = "Hello, ";
string tmp1 = new String( msg + "Tuan Tran" );
string msg = tmp1; // "Hello " is garbage.
string tmp2 = new String( msg + ". Today is " );
msg = tmp2; // "Hello Tuan Tran" is garbage.
string tmp3 = new String( msg + DateTime.Now.ToString( ) );
msg = tmp3; // "Hello Tuan Tran. Today is " is garbage.
2.1.1. The fix: string.Concat, StringBuilder and string.Format
Overall, StringBuilder is always the fastest one.
StringBuilder s = new StringBuilder();
s.Append("Tuan Tran"); s.Append(" Today is ");
blah blah blah
However, for C# 6.0 as mentioned above, its compiler is smart enough to emit the most efficient native code.
So in short, you can use string.Concat to join simple strings, StringBuilder to build bigger strings, and string.Format when you want to join strings from other data types, or want to format it in some way.
2.2. Mistake 2: null checks – comparing to the empty string
Dead simple, right?
string s = "";
if(s == null || s == "")
{
//do something here;
}
There is a more modern way
string s = "";
if(string.IsNullOrEmpty(s))
{
//do something here;
}
And if you want to compare 2 strings, use string.Equal
2.3. Conclusion
Take the time to learn the methods already written for string, and use them in the right situations. Microsoft already wrote them for you, and they already optimized those methods’ performance — so why not use them.
Here is the MSDN documentation for string:
https://docs.microsoft.com/en-us/dotnet/api/system.string?view=netcore-2.2