Jamal's Professional Blog

Friday, 27 June 2008

String.Empty vs. ""

During my .NET years I've been many times asked about the differences between C# String.Empty and empty literal (""). Which one is more preferable?! Even when developing C# and .NET coding-style and implementation guidelines this has always been challenging as every programmer has his own ideas and experience.

A) string s1 = String.Empty;
B) string s2 = "";

Here is some advise:

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 A is ldsfld String.Empty which simply pushes the reference of the specified field into local stack after executing class's static constructor for the first time - 5 bytes instruction. Please consider String.Empty assigns the empty literal ("") to a static field only once during the first access to the String class and that's totally not a big deal; the resulting reference to "" will be reused during your application domain lifetime.

At 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 penalties during JIT compilation of the containing method.

Coding Style
Throughout my professional career and when developing proper coding-style, I've considered we're not only talking about technology; it always involves aesthetics and human nature!!! Increasing readability reducing maintenance cost is a generally accepted coding-style design measure.

Picking String.Empty syntax usually results into higher readability score compared to the "" syntax. I'll definitely go for the first one as feel more comfortable when reading and skimming the code, not to mention how error-prone could the latter be when confused with " " (single white-space string literal).

Labels: , , ,

5 Comments:

  • Yes, but it's not IL code that runs on the processor. My blog post (http://msmvps.com/blogs/senthil/archive/2008/06/27/string-empty-versus-quot-quot.aspx) compares the JITted code (x86), which shows that there is no difference at all.

    By Blogger S. Senthil Kumar, At 30 June 2008 09:31  

  • Unforetunately I cannot agree anymore; check my comments on the post for more info please...

    When writing this post I was already aware of the "possibility" of JIT optimisations here! Honestly I'd have done this if I was the guy. Still decided to label the "" version lower in performance concerns as has much dependency on CLR implementation, whilst the String.Empty version would be fast in almost all (today and future) implemenations even those not-yet-optimised ones.

    I'd also like to admit I loved to check MS SSCLI code ensuring how JIT-compiler handles this partiucular situation. unfortunately busy busy as always... sure you understand :)

    By Blogger Jamal Mavadat, At 30 June 2008 14:31  

  • Just to clearify the performance penalty is soooo small, and even could be ignored in most cases, especially in the world where we're all surrounded by XML and ...

    Only as an example the way C# 3.0 compiler handles expression trees is much much bigger than these small tiny bits!

    By Blogger Jamal Mavadat, At 30 June 2008 14:40  

  • Hmm, you say the call instruction is not the real assignment - it's not. It's the mov instruction before the call that is the assignment. It moves the reference to the string object to ecx and then makes a call to DoNothing. You do agree that the code generated for DoNothing will be the same always, don't you?

    And yes, I agree it's more of a stylistic issue than a perf one.

    By Blogger S. Senthil Kumar, At 30 June 2008 19:55  

  • OOPS!!! Sorry matey :)

    Anyway, the constant literal case ("") goes through internal AppDomain (well Module actually) hash-table (string interning) which is slower during JIT compilation. This is supposed to happen once for every "" usage unless exclusively optimised which makes it implementation-specific though.

    At the other hand, the static field alternative (String.Empty) goes through the same process only once for the whole AppDomain speeding up JIT compilation!

    Both gains and pains are not enough making you ponder; there are lots of performance gains available out there by clever architectural decisions and ...

    Post update (4th paragraph) to be clear. Very special thanks for your helpful comments.

    By Blogger Jamal Mavadat, At 1 July 2008 09:49  

Post a Comment



<< Home