Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String.Replace() vs. StringBuilder.Replace()

I have a string in which I need to replace markers with values from a dictionary. It has to be as efficient as possible. Doing a loop with a string.replace is just going to consume memory (strings are immutable, remember). Would StringBuilder.Replace() be any better since this is was designed to work with string manipulations?

I was hoping to avoid the expense of RegEx, but if that is going to be a more efficient then so be it.

Note: I don't care about code complexity, only how fast it runs and the memory it consumes.

Average stats: 255-1024 characters in length, 15-30 keys in the dictionary.

like image 674
Dustin Davis Avatar asked Jun 29 '11 17:06

Dustin Davis


People also ask

Why did you use StringBuilder instead of string?

StringBuilder is used to represent a mutable string of characters. Mutable means the string which can be changed. So String objects are immutable but StringBuilder is the mutable string type.

Why is StringBuilder better than string Java?

StringBuilder is speedy and consumes less memory than a string while performing concatenations. This is because string is immutable in Java, and concatenation of two string objects involves creating a new object.

How do I replace a character in StringBuilder?

replace() method replaces the characters in a substring of this sequence with characters in the specified String. The substring begins at the specified start and extends to the character at index end - 1 or to the end of the sequence if no such character exists.

What does the replace () method do?

The replace() method searches a string for a specified character, and returns a new string where the specified character(s) are replaced.


2 Answers

Using RedGate Profiler using the following code

class Program     {         static string data = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";         static Dictionary<string, string> values;          static void Main(string[] args)         {             Console.WriteLine("Data length: " + data.Length);             values = new Dictionary<string, string>()             {                 { "ab", "aa" },                 { "jk", "jj" },                 { "lm", "ll" },                 { "yz", "zz" },                 { "ef", "ff" },                 { "st", "uu" },                 { "op", "pp" },                 { "x", "y" }             };              StringReplace(data);             StringBuilderReplace1(data);             StringBuilderReplace2(new StringBuilder(data, data.Length * 2));              Console.ReadKey();         }          private static void StringReplace(string data)         {             foreach(string k in values.Keys)             {                 data = data.Replace(k, values[k]);             }         }          private static void StringBuilderReplace1(string data)         {             StringBuilder sb = new StringBuilder(data, data.Length * 2);             foreach (string k in values.Keys)             {                 sb.Replace(k, values[k]);             }         }          private static void StringBuilderReplace2(StringBuilder data)         {             foreach (string k in values.Keys)             {                 data.Replace(k, values[k]);             }         }     } 
  • String.Replace = 5.843ms
  • StringBuilder.Replace #1 = 4.059ms
  • Stringbuilder.Replace #2 = 0.461ms

String length = 1456

stringbuilder #1 creates the stringbuilder in the method while #2 does not so the performance difference will end up being the same most likely since you're just moving that work out of the method. If you start with a stringbuilder instead of a string then #2 might be the way to go instead.

As far as memory, using RedGateMemory profiler, there is nothing to worry about until you get into MANY replace operations in which stringbuilder is going to win overall.

like image 172
Dustin Davis Avatar answered Sep 20 '22 16:09

Dustin Davis


This may be of help: https://docs.microsoft.com/en-us/archive/blogs/debuggingtoolbox/comparing-regex-replace-string-replace-and-stringbuilder-replace-which-has-better-performance

The short answer appears to be that String.Replace is faster, although it may have a larger impact on your memory footprint / garbage collection overhead.

like image 31
RMD Avatar answered Sep 22 '22 16:09

RMD