Home

Search

C# string.Intern and IsInterned

Use the string.Intern method. Benchmark the string intern pool and test IsInterned.

dot net perls

Intern. The string.Intern method optimizes string memory and performance. It allows us to put strings in the runtime's shared string pool.

Notes, usage. We call IsInterned to see if an interned string exists. Most programs will not use Intern or IsInterned. But it helps to know what they are.

An example. The Intern static method can improve performance of string comparisons by more than two times. Intern puts strings in a common string pool maintained by the .NET runtime.Static
Note: The string pool is an optimization mainly for string literals, which are strings that you place directly in your code.
Literals: String literals are surrounded by quotes. They are constant and immutable—meaning you can't change them.
String Literal
C# program that uses string.Intern class Program { static void Main() { // Regular string literal. string s1 = "I'm a string literal."; // Const string literal. const string s2 = "I'm also a string literal."; // Verbatim string literal. string s3 = @"I'm a string literal with the verbatim syntax."; } }

Example 2. You cannot change string literals. However, you can reassign the variable that points to them. This changes the reference, not the value.
Here: In this program, we modify a string reference only. The actual data, the literals, are left alone.
C# program that reassigns string literals class Program { static void Main() { string s = "I'm a string literal."; s = "I'm another literal."; } }

Example 3. Intern takes a string you build up at runtime and basically turns it into a string literal. This makes comparisons much faster.
Part A: This string is generated at runtime, so it is not from the internal string pool. It is on the heap.
Part B: We take the string created at runtime, and add it to the string pool. Now it is similar to a string literal.
C# program that in terns string using System.Text; class Program { static void Main() { // Part A: create string at runtime. string s1 = new StringBuilder().Append("cat").Append(" and dog").ToString(); // Part B: get interned string added at runtime. string s2 = string.Intern(s1); } }

Equals. It is faster to compare interned strings. The method that implements string comparisons with always checks references first. If the references are equal, the comparison succeeds.String Equals
Next: The Equals method is how the == operator is implemented in the .NET Framework. The first part tests the references for equality.
Also: EqualsHelper compares all the characters in a loop and is slower. It is called if the other conditions do not short-circuit.
Implementation of string.Equals: C# public static bool Equals(string a, string b) { return ((a == b) || (((a != null) && (b != null)) && EqualsHelper(a, b))); }

Benchmark, Intern. Here we test the performance of comparing strings that have been interned with string.Intern. The tests were repeated 10 times and averaged.True, False
Version 1: In this version of the code, we compare string literals against a string that has not been interned.
Version 2: Here we test string literals against a string that had string.Intern called upon it. We use interned strings.
Result: String.Intern improves performance by more than 4 times when the string comparison is always true.
Info: The string.Intern method only speeds things up when 2 strings are equal, and both are interned.
C# program that benchmarks string.Intern tests using System; using System.Text; class Program { static void Main() { // Create string at runtime. StringBuilder b = new StringBuilder().Append("cat ").Append( "and ").Append("dog"); // Get runtime string. string s1 = b.ToString(); // Get string pool reference to string. string s2 = string.Intern(s1); int m = 10000; for (int v = 0; v < 10; v++) { int d = 0; long t1 = Environment.TickCount; // Version 1: test regular string. for (int i = 0; i < m; i++) { for (int a = 0; a < m; a++) { if (s1 == "cat and rabbit") { d++; // false } if (s1 == "cat and dog") { d--; // true } } } long t2 = Environment.TickCount; // Version 2: test interned string. for (int i = 0; i < m; i++) { for (int a = 0; a < m; a++) { if (s2 == "cat and rabbit") { d++; // false } if (s2 == "cat and dog") { d--; // true } } } // Write results. long t3 = Environment.TickCount; Console.Write((t2 - t1)); Console.WriteLine("," + (t3 - t2)); } Console.ReadLine(); } } Output No string.Intern: 1540 ms With string.Intern: 736 ms [faster]

IsInterned. With string.IsInterned, you can test whether a string is present in the internal table, without adding it if it is not. It receives a string reference and returns one too.
Info: If the internal string is found, that reference is returned. If no internal string is present, a null reference is returned.
Null
First: A string literal is tested. This reveals that string literals are always present in the intern table.
And: On the other hand, a dynamically constructed string is not present in the intern table.
Null: IsInterned will return null in this case. It will not add the string to the intern table.
C# program that uses IsInterned method using System; class Program { static void Main() { // See if a string literal is interned. string value1 = "cat"; string value2 = string.IsInterned(value1); Console.WriteLine(value2); // See if a dynamically constructed string is interned. string value3 = "cat" + 1.ToString(); string value4 = string.IsInterned(value3); Console.WriteLine(value4 == null); } } Output cat True

Usage. In most programs, you do not need to use Intern or IsInterned. But if you use the intern table in other places, you might want to use the string.IsInterned method.

A summary. String.Intern and IsInterned act on the string intern pool. Intern can make string comparisons four or more times faster. The string pool is an important optimization.

Home

© 2007-2020 sam allen. send bug reports to info@dotnetperls.com.