C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
It actually allocates a new string each time it is called on an int variable. We use an extension method. We use a lookup table and avoid this allocation in some cases.
Example. First we demonstrate code that introduces an extension method called ToStringLookup. This method can be used on any integer variable to use the ToString method only if the string is not found in the lookup table.
Internally: The ToStringExtensions class stores a static string array: the lookup table. It contains 200 string literals in the metadata.
Then: The ToStringLookup extension method checks for values that are in the lookup table, and otherwise calls ToString.
Extension method class file: C# using System.Globalization; static class ToStringExtensions { // Lookup table. static string[] _cache = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "100", "101", "102", "103", "104", "105", "106", "107", "108", "109", "110", "111", "112", "113", "114", "115", "116", "117", "118", "119", "120", "121", "122", "123", "124", "125", "126", "127", "128", "129", "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "140", "141", "142", "143", "144", "145", "146", "147", "148", "149", "150", "151", "152", "153", "154", "155", "156", "157", "158", "159", "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", "170", "171", "172", "173", "174", "175", "176", "177", "178", "179", "180", "181", "182", "183", "184", "185", "186", "187", "188", "189", "190", "191", "192", "193", "194", "195", "196", "197", "198", "199" }; // Lookup table last index. const int _top = 199; public static string ToStringLookup(this int value) { // See if the integer is in range of the lookup table. // ... If it is present, return the string literal element. if (value >= 0 && value <= _top) { return _cache[value]; } // Fall back to ToString method. return value.ToString(CultureInfo.InvariantCulture); } } C# program that uses extension method using System; class Program { static void Main() { // Use the ToString lookup extension method. Console.WriteLine((-100).ToStringLookup()); Console.WriteLine(5.ToStringLookup()); Console.WriteLine(199.ToStringLookup()); Console.WriteLine(200.ToStringLookup()); } } Output -100 5 199 200
The ToStringLookup method is introduced in the ToStringExtensions static class. It uses the extension method syntax. In the Main entry point, we call the ToStringLookup extension method on different instance expressions.
And: ToStringLookup returns a string representation of each integer, as ToString would. But it avoids an allocation for two of the calls.
Performance. The ToString lookup method shown in this article is much faster when you call ToString on an integer of value 0 to 199. In that range, a string literal is simply returned. This avoids an entire heap allocation.
Note: In the .NET Framework, a string requires 20 bytes of memory as well as 2 bytes for each character.
Tip: The ToStringLookup method avoids this overhead on multiple values of 0-199.
Also, the method shown above only stores the first 200 strings in the metadata as string literals. You can store many more strings. This would also help performance. You could generate a C# file with code.
Further: You could use a Dictionary. But this could introduce threading problems. It might cause extreme memory usage.
Results: In my tests, a ToString call on a zero integer requires about 100 ns. A ToStringLookup call on a zero requires about 3 ns.
Summary. We looked at a C# cache class that can store common string representations of integers. The ToStringLookup method can then be used to optimize the conversion of integers to strings.
Thus: This results in less overall memory usage. It leads to better performance. It adds complexity and greater initial memory usage.