On Monday, I was corrected in my assertion that creating multiple empty strings would create multiple objects. Turns out the compiler automatically puts all of the strings that are exactly the same in a “string pool” so that there is only ever one empty string in the entire application you’ve created.
Duh! I should have known this, or at least I should have expected that this was so since it has been true with every other compiled language I’ve worked with.
But what I didn’t know and couldn’t expect is that we can make use of this string pool programmatically as well.
Why would you want to do this yourself?
Keep in mind that string concatenation in .NET requires the creation of a new object. So, code such as this,
String a = "abcd"; String b = "efgh"; a += b;
creates a new object at line 3 every time it is executed.
So that if we add the following line:
b = "abcdefgh";
if (a == b) Trace.Write("A and B contain the same data"); if (String.ReferenceEquals(a,b)) Trace.Write("A and B are the same object");
String.Intern Consolidates The Data
By using String.Intern() we can get both evaluations to be true.
String a = "abcd"; String b = "efgh"; a = String.Intern(a + b); b = "abcdefgh";
Now both evaluations above will be true because line 3 places the string “abcdefgh” in the pool and line 4 uses that same string from the pool to assign to b. Where we might have created two objects, we are now only creating one and referring to it both times.
You could also use String.IsInterned(string) to determine if a string has already been placed in the string pool and execute optional code based on that.
When Would You Use This?
I still stand by my statement that optimizations should be saved for last. You would not do this if this was the only place where you were doing the concatenation. But you might consider doing this if your concatenations were in a loop that was taking a significant amount of processing time.
Other things you might also want to consider would be to consolidate concatenations on the same line and/or using the StringBuilder class for concatenations. Keep in mind that StringBuilder is only really useful once you get past three concatenations due to the overhead of creating the StringBuilder object vs. creating new objects during the normal concatenation process.
Other post in Advanced CSharp
- Two Interfaces. Same Method. Two meanings. - September 29th, 2008
- Readonly variables in CSharp? Really?! - October 29th, 2008
- Dispose with Using - November 10th, 2008
- Delegates in .NET - December 4th, 2008
- Using Sealed in CSharp - December 8th, 2008
- CSharp checked and unchecked - December 11th, 2008
- Unsafe Mode in C# - December 15th, 2008
- Volatile variables and CSharp threads - December 22nd, 2008
- What is the global keyword in CSharp? - December 29th, 2008
- CSharp fixed keyword - January 5th, 2009
- using - There's more there than you are using - February 2nd, 2009
- Removing Warnings from CSharp Compile Cycle - March 10th, 2009
- Just say “No!” to C# Regions? Really?! - April 16th, 2009
- C# “” better than string.Empty? - April 20th, 2009
- .Net String Pool – Not Just For The Compiler - April 22nd, 2009
- CSharp ?? Operator - May 18th, 2009
- Using VB.NET From CSharp - July 1st, 2009
- What is .NET’s Object.GetHashCode() Used For? - August 5th, 2009
- ASP.NET Substitution Control - October 22nd, 2009
- Transaction Tracking Typed Datasets Using SqlTransaction - July 20th, 2010
- CSharp's Property Shortcuts - July 17th, 2012
- && vs & and | vs ||... What's the difference? - August 21st, 2012
- Advanced CSharp - yield - November 27th, 2012
- Making values nullable - December 18th, 2012
- Stackalloc in CSharp - January 22nd, 2013
- Dispose, Finalize and SuppressFinalize - June 12th, 2013
- CSharp Numeric Overflows - July 3rd, 2014
- CSharp IDisposable Confusion - July 17th, 2014
- Why Get Certified? - July 24th, 2014
- Running Selenium In Parallel With Any .NET Unit Testing Tool - July 31st, 2014
- Browser Automation in .NET w/ Chromium - July 9th, 2015