Throughout my MS.NET years I was occasionally asked about differences between C#
String.Empty and the empty string literal (
""). And also when implementing C# and .NET coding-style documents this has always been challenging since everybody has his own opinion, experience, and taste.
A)
string s1 = String.Empty;
B)
string s2 = "";
Here’s some advice which might come handy:
Performance
String.Empty is a static read-only public field which is initialised by the static constructor of the
String class. Simplified MSIL code generated for statement
A is
ldsfld String.Empty; this simply pushes the reference of a specific field (String.Empty in this case) into local stack of your executing method after invoking static constructor of the class if not previously executed – this is a 5 bytes instruction though. Note that
String.Empty field actually assigns the empty literal (
"") to a static field only once and during first access to the
String class and this is no big deal; then the resulting reference to constant
"" value (from string pool - see below) will be reused for your application domain lifetime (your windows process whatever it is, your hosting environment whatever it is…)
On the other hand, the C# statement
B results into
ldstr "" MSIL statement; again a 5 bytes instruction.
ldstr pushes the supplied literal into AppDomain's internal string pool (CLR internal
GlobalStringLiteralMap C++ class) if not previously loaded into the map. The reason is obvious: more efficient memory usage by sharing string literals in memory - a technique called
string interning.
When comparing the two alternatives, statement
A is so straightforward in CLR implementation making it simple and fast, whilst statement
B goes through the overhead of checking the AppDomain's string pool (an internal hash-table) bringing very small performance penalty. BUT:
- A and B have JIT compile-time differences and JIT-Compiler will eventually generate nearly same results in either cases; this also implies there is absolutely no performance penalty when your assembly [not framework assemblies] is NGENed (using ngen.exe for example)
- During JIT-compilation of your executing method there is this very small (nearly zero) performance penalty which is paid only once. In other words, worrying about performance differences between statement A and B is pointless.
Coding Style
Well, whenever it comes to developing an effective coding-style document, I've realised we're not only talking about technology and it also involves aesthetics and human nature! I suppose we all do agree that increasing readability to at least reduce maintenance costs is a generally accepted coding-style design measure; this may hardly become a baseline for coding-style challenges.
What I'll say here, is only my personal opinion and favourite syntax supported by 16+ years of extensive coding effort - yet it does not necessarily reflect community preference: the
String.Empty syntax usually results into higher readability by adding distinctness compared to the
"" syntax. I'll definitely go for the first one as I feel more comfortable when reviewing and skimming someone else’s code. The
"" syntax is not visually clear enough [needs more attention to see whether or not spaces are contained - could make eyes fatigued for very lengthy code]. Also, it is not clear with non-fixed-size fonts where the number of involved spaces matters [in very rare cases – like when using spaces for print or control alignments]. This is because these fonts usually have narrowed space characters not appropriate for extensive coding.
Labels: .NET, C-Sharp, CLR, Microsoft