Monthly Archives: June 2008

This is one topic that keeps popping up every now and then. A lot of people seem to be curious about the performance implications of using one versus the other, and not unexpectedly, a lot of different answers come up.

To settle it once for all, here’s a small program that uses both of them.

As you can see above, Method1 and Method2 call DoNothing, passing “” and string.Empty respectively. Now how do we compare these two? Easy, just look at the jitted code – after all, that’s what is going to run on the machine.

We’ll use Windbg to disassemble the code after the JITter did its job. And if you’re wondering why Method1 and Method2 have been called twice, now you know why – the second time around, we can look at the JITted code that was generated as part of the first time execution of each of those methods.

So breaking into the debugger at Console.ReadLine() and dumping the method descriptors for Program

shows that, surprise surprise, the generated assembly code is identical.The only difference is the address referenced in the mov instruction.

So there you have it – the JITter generates the same code whether you use String.Empty or “”, and there should no difference in performance.

PS : It’s interesting to note that the two addresses are different, even though the string contents are the same. Address 2E4303Ch in the disassembly for Method1 is the address referring to an interned string object with the content “”. You can verify that by creating another string variable initialized to “” and disassembling that code – the same address (2E4303Ch) will be referenced there as well. What’s surprising is that the address referenced in Method2 is different – which means the string object referenced by string.Empty is not the interned object. Wonder why – maybe because it’s ngen’ned code?