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

前端 未结 9 1552
萌比男神i
萌比男神i 2020-11-28 05:04

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

相关标签:
9条回答
  • 2020-11-28 05:51

    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.

    0 讨论(0)
  • 2020-11-28 05:52

    My two cents here, I just wrote couple of lines of code to test how each method performs and, as expected, result is "it depends".

    For longer strings Regex seems to be performing better, for shorter strings, String.Replace it is. I can see that usage of StringBuilder.Replace is not very useful, and if wrongly used, it could be lethal in GC perspective (I tried to share one instance of StringBuilder).

    Check my StringReplaceTests GitHub repo.

    0 讨论(0)
  • 2020-11-28 05:57

    Yes, StringBuilder will give you both gain in speed and memory (basically because it won't create an instance of a string each time you will make a manipulation with it - StringBuilder always operates with the same object). Here is an MSDN link with some details.

    0 讨论(0)
提交回复
热议问题