Fastest way to replace multiple strings in a huge string

后端 未结 8 734
野的像风
野的像风 2020-12-13 04:51

I m looking for the fastest way to replace multiple (~500) substrings of a big (~1mb) string. Whatever I have tried it seems that String.Replace is the fastest way of doing

8条回答
  •  盖世英雄少女心
    2020-12-13 05:05

    Using unsafe and compiled as x64

    result:

    Implementation       | Exec   | GC
    #1 Simple            | 4706ms |  0ms
    #2 Simple parallel   | 2265ms |  0ms
    #3 ParallelSubstring |  800ms | 21ms
    #4 Fredou unsafe     |  432ms | 15ms
    

    take the code of Erti-Chris Eelmaa and replace my previous one with this.

    I don't think I will do another iteration but i did learn a few thing with unsafe which is a good thing :-)

        private unsafe static void FredouImplementation(string input, int inputLength, string replace, string[] replaceBy)
        {
            var indexes = new List();
    
            //input = "ABCDABCABCDABCABCDABCABCDABCD";
            //inputLength = input.Length;
            //replaceBy = new string[] { "AA", "BB", "CC", "DD", "EE" };
    
            //my own string.indexof to save a few ms
            int len = inputLength;
    
            fixed (char* i = input, r = replace)
            {
                int replaceValAsInt = *((int*)r);
    
                while (--len > -1)
                {
                    if (replaceValAsInt == *((int*)&i[len]))
                    {
                        indexes.Add(len--);
                    }
                }                
            }
    
            var idx = indexes.ToArray();
            len = indexes.Count;
    
            Parallel.For(0, replaceBy.Length, l =>
                Process(input, inputLength, replaceBy[l], idx, len)
            );
        }
    
        private unsafe static void Process(string input, int len, string replaceBy, int[] idx, int idxLen)
        {
            var output = new char[len];
    
            fixed (char* o = output, i = input, r = replaceBy)
            {
                int replaceByValAsInt = *((int*)r);
    
                //direct copy, simulate string.copy
                while (--len > -1)
                {
                    o[len] = i[len];
                }
    
                while (--idxLen > -1)
                {
                    ((int*)&o[idx[idxLen]])[0] = replaceByValAsInt;
                }
            }
    
            //Console.WriteLine(output);
        }
    

提交回复
热议问题