5 вариантов unescape - угадайте какой самый быстрый (неожида
От: Shmj Ниоткуда  
Дата: 29.11.19 23:09
Оценка:
Нужно чтобы в строке не было символа '\n'. Для этого:

1. Заменяем все "\\" на "\\\\".
2. Заменяем все "\n" на "\\n".

Это все понятно. Самый смак — как возвернуть все взад...

Накидал 5 вариантов, см. полный код:

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();
            
            sw.Reset();
            sw.Start();

            //var unescaped = Test1(escaped);
            //var unescaped = Test2(escaped);
            //var unescaped = Test3(escaped);
            //var unescaped = Test4(escaped);
            var unescaped = Test5(escaped);

            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();
        }
    }


Сокращенная версия для запуска: https://dotnetfiddle.net/52uORv

И вопрос: как вы думаете, какой вариант самый быстрый? Как сделать быстрее?
Отредактировано 29.11.2019 23:13 Shmj . Предыдущая версия .
escape
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.