Информация об изменениях

Сообщение Re[4]: 5 вариантов unescape - угадайте какой самый быстрый ( от 30.11.2019 2:58

Изменено 30.11.2019 3:07 Shmj

Re[4]: 5 вариантов unescape - угадайте какой самый быстрый (неожида
Здравствуйте, adetkov, Вы писали:

A>| Method | Mean | Error | StdDev |

A>|--------- |----------:|---------:|---------:|
A>| Unescape | 74.69 ms | 1.471 ms | 2.063 ms |
A>| Test5 | 126.85 ms | 2.401 ms | 2.128 ms |

Странно, у меня другие результаты:

  Скрытый текст
Test6=206
Test5=184

Test6=194
Test5=200

Test6=205
Test5=182

Test6=209
Test5=181

Test6=204
Test5=184

Test6=204
Test5=186

Test6=206
Test5=187

Test6=208
Test5=272

Test6=223
Test5=176

Test6=206
Test5=189


Test5 практически всегда быстре.

Полный код:

  Скрытый текст
using System;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Random r = new Random();

            var sb = new StringBuilder(2000000 * 7);

            sb.Append("test1\ntest2\\n\\\\test3");

            for (int i = 0; i < 2000000; i++)
            {
                if (r.Next(1, 3) == 1)
                    sb.Append("\\");

                if (r.Next(1, 3) == 1)
                    sb.Append("\\");

                if (r.Next(1, 3) == 1)
                    sb.Append("\\n");

                if (r.Next(1, 4) == 3)
                    sb.Append("\n");

                sb.Append("word");
            }

            var input = sb.ToString();

            var escaped = input.Replace("\\", "\\\\").Replace("\n", "\\n");

            var sw = new Stopwatch();


            for (int i = 0; i < 10; i++)
            {
                sw.Reset();
                sw.Start();

                Test6(escaped);
                sw.Stop();
                Console.WriteLine("Test6=" + sw.ElapsedMilliseconds);


                sw.Reset();
                sw.Start();

                Test5(escaped);
                sw.Stop();
                Console.WriteLine("Test5=" + sw.ElapsedMilliseconds);

                Console.WriteLine();
            }

            sw.Reset();
            sw.Start();

            //var unescaped = Test1(escaped); // 1235
            //var unescaped = Test2(escaped); mamma mia!
            //var unescaped = Test3(escaped); // 891
            //var unescaped = Test4(escaped); // 289
            //var unescaped = Test5(escaped); // 183
            var unescaped = Test6(escaped); // 208

            sw.Stop();

            Console.WriteLine(sw.ElapsedMilliseconds);
            Console.ReadLine();
            Console.WriteLine(unescaped.Equals(input));
        }

        static string Test1(string escaped)
        {
            var guid = Guid.NewGuid().ToString();
            return escaped.Replace("\\\\", guid).Replace("\\n", "\n").Replace(guid, "\\");
        }

        static string Test2(string escaped)
        {
            return escaped.Split(new[] {"\\\\"}, StringSplitOptions.None)
                .Aggregate((seed, next) => seed + "\\" + next.Replace("\\n", "\n"));
        }

        static string Test3(string escaped)
        {
            var parts = escaped.Split(new[] {"\\\\"}, StringSplitOptions.None)
                .Select(part => part.Replace("\\n", "\n"));
            return string.Join("\\", parts);
        }

        static string Test4(string escaped)
        {
            var unescaped = new StringBuilder(escaped.Length);

            bool slash = false;

            foreach (var ch in escaped)
            {
                if (slash)
                {
                    if ('\\' == ch)
                        unescaped.Append('\\');

                    if ('n' == ch)
                        unescaped.Append('\n');

                    slash = false;
                    continue;
                }

                if ('\\' == ch)
                    slash = true;
                else
                    unescaped.Append(ch);
            }

            return unescaped.ToString();
        }

        static string Test5(string escaped)
        {
            var unescaped = new StringBuilder(escaped.Length);

            int currentIndex = 0;

            while (true)
            {
                var slashIndex = escaped.IndexOf('\\', currentIndex);

                if (-1 == slashIndex)
                {
                    unescaped.Append(escaped, currentIndex, escaped.Length - currentIndex);
                    break;
                }

                unescaped.Append(escaped, currentIndex, slashIndex - currentIndex);
                currentIndex = slashIndex;

                var nextChar = escaped[slashIndex + 1];

                switch (nextChar)
                {
                    case '\\':
                        unescaped.Append('\\');
                        break;
                    case 'n':
                        unescaped.Append('\n');
                        break;
                    default:
                        throw new InvalidOperationException("nextChar=" + nextChar);
                }

                currentIndex++;
                currentIndex++;
            }

            return unescaped.ToString();
        }

        private static string Test6(string str)
        {
            char[] array = str.ToCharArray();
            int cur = 0;
            bool waitControl = false;

            for (int i = 0; i < array.Length; i++)
            {
                if (!waitControl)
                {
                    if (array[i] == '\\')
                    {
                        waitControl = true;
                        continue;
                    }

                    array[cur++] = array[i];
                    continue;
                }

                waitControl = false;


                switch (array[i])
                {
                    case 'n':
                        array[cur++] = '\n';
                        break;
                    case '\\':
                        array[cur++] = '\\';
                        break;
                    default:
                        throw new Exception("Unexpected control symbol");
                }
            }

            return new string(array, 0, cur);
        }
    }
}
Re[4]: 5 вариантов unescape - угадайте какой самый быстрый (
Здравствуйте, adetkov, Вы писали:

A>| Method | Mean | Error | StdDev |

A>|--------- |----------:|---------:|---------:|
A>| Unescape | 74.69 ms | 1.471 ms | 2.063 ms |
A>| Test5 | 126.85 ms | 2.401 ms | 2.128 ms |

Странно, у меня другие результаты:

  Скрытый текст
Test6=206
Test5=184

Test6=194
Test5=200

Test6=205
Test5=182

Test6=209
Test5=181

Test6=204
Test5=184

Test6=204
Test5=186

Test6=206
Test5=187

Test6=208
Test5=272

Test6=223
Test5=176

Test6=206
Test5=189


Test5 практически всегда быстре.

Полный код:

  Скрытый текст
using System;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Random r = new Random();

            var sb = new StringBuilder(2000000 * 7);

            sb.Append("test1\ntest2\\n\\\\test3");

            for (int i = 0; i < 2000000; i++)
            {
                if (r.Next(1, 3) == 1)
                    sb.Append("\\");

                if (r.Next(1, 3) == 1)
                    sb.Append("\\");

                if (r.Next(1, 3) == 1)
                    sb.Append("\\n");

                if (r.Next(1, 4) == 3)
                    sb.Append("\n");

                sb.Append("word");
            }

            var input = sb.ToString();

            var escaped = input.Replace("\\", "\\\\").Replace("\n", "\\n");

            var sw = new Stopwatch();


            for (int i = 0; i < 10; i++)
            {
                sw.Reset();
                sw.Start();

                Test6(escaped);
                sw.Stop();
                Console.WriteLine("Test6=" + sw.ElapsedMilliseconds);


                sw.Reset();
                sw.Start();

                Test5(escaped);
                sw.Stop();
                Console.WriteLine("Test5=" + sw.ElapsedMilliseconds);

                Console.WriteLine();
            }

            sw.Reset();
            sw.Start();

            //var unescaped = Test1(escaped); // 1235
            //var unescaped = Test2(escaped); mamma mia!
            //var unescaped = Test3(escaped); // 891
            //var unescaped = Test4(escaped); // 289
            //var unescaped = Test5(escaped); // 183
            var unescaped = Test6(escaped); // 208

            sw.Stop();

            Console.WriteLine(sw.ElapsedMilliseconds);
            Console.ReadLine();
            Console.WriteLine(unescaped.Equals(input));
        }

        static string Test1(string escaped)
        {
            var guid = Guid.NewGuid().ToString();
            return escaped.Replace("\\\\", guid).Replace("\\n", "\n").Replace(guid, "\\");
        }

        static string Test2(string escaped)
        {
            return escaped.Split(new[] {"\\\\"}, StringSplitOptions.None)
                .Aggregate((seed, next) => seed + "\\" + next.Replace("\\n", "\n"));
        }

        static string Test3(string escaped)
        {
            var parts = escaped.Split(new[] {"\\\\"}, StringSplitOptions.None)
                .Select(part => part.Replace("\\n", "\n"));
            return string.Join("\\", parts);
        }

        static string Test4(string escaped)
        {
            var unescaped = new StringBuilder(escaped.Length);

            bool slash = false;

            foreach (var ch in escaped)
            {
                if (slash)
                {
                    if ('\\' == ch)
                        unescaped.Append('\\');

                    if ('n' == ch)
                        unescaped.Append('\n');

                    slash = false;
                    continue;
                }

                if ('\\' == ch)
                    slash = true;
                else
                    unescaped.Append(ch);
            }

            return unescaped.ToString();
        }

        static string Test5(string escaped)
        {
            var unescaped = new StringBuilder(escaped.Length);

            int currentIndex = 0;

            while (true)
            {
                var slashIndex = escaped.IndexOf('\\', currentIndex);

                if (-1 == slashIndex)
                {
                    unescaped.Append(escaped, currentIndex, escaped.Length - currentIndex);
                    break;
                }

                unescaped.Append(escaped, currentIndex, slashIndex - currentIndex);
                currentIndex = slashIndex;

                var nextChar = escaped[slashIndex + 1];

                switch (nextChar)
                {
                    case '\\':
                        unescaped.Append('\\');
                        break;
                    case 'n':
                        unescaped.Append('\n');
                        break;
                    default:
                        throw new InvalidOperationException("nextChar=" + nextChar);
                }

                currentIndex++;
                currentIndex++;
            }

            return unescaped.ToString();
        }

        private static string Test6(string str)
        {
            char[] array = str.ToCharArray();
            int cur = 0;
            bool waitControl = false;

            for (int i = 0; i < array.Length; i++)
            {
                if (!waitControl)
                {
                    if (array[i] == '\\')
                    {
                        waitControl = true;
                        continue;
                    }

                    array[cur++] = array[i];
                    continue;
                }

                waitControl = false;


                switch (array[i])
                {
                    case 'n':
                        array[cur++] = '\n';
                        break;
                    case '\\':
                        array[cur++] = '\\';
                        break;
                    default:
                        throw new Exception("Unexpected control symbol");
                }
            }

            return new string(array, 0, cur);
        }
    }
}


Вы какие данные подаете на вход?