Быстрый строковый парсинг в C#

Что самый быстрый путь состоит в том, чтобы проанализировать строки в C#?

В настоящее время я просто использую строковую индексацию (string[index]) и код работает обоснованно, но я не могу не думать, что непрерывная проверка диапазона, которую делает индексное средство доступа, должна добавлять что-то.

Так, я задаюсь вопросом, какие методы я должен рассмотреть для стимулирования его. Это мои начальные мысли/вопросы:

  1. Используйте методы как string.IndexOf() и IndexOfAny() находить символы интересным. Они быстрее, чем ручное сканирование строки string[index]?
  2. Используйте regex's. Лично, мне не нравится regex, поскольку я нахожу их трудными поддержать, но они, вероятно, будут быстрее, чем ручное сканирование строки?
  3. Используйте небезопасный код и указатели. Это устранило бы индексную проверку диапазона, но я считал что небезопасная привычка кода, выполненная в недоверяемых средах. Каковы точно последствия этого? Это означает, что целый блок не загрузит/выполнит, или будет только код отмеченный небезопасный мусор для выполнения? Библиотекой можно было потенциально пользоваться во многих средах, таким образом, смочь отступить к более медленному, но более совместимому режиму будет хорошо.
  4. Что еще я мог бы рассмотреть?

NB: который я должен сказать, строки, которые я анализирую, мог быть довольно большим (скажите, что 30k) и в пользовательском формате, для которого нет никакого стандартного синтаксического анализатора.NET. Кроме того, производительность этого кода не супер очень важна, таким образом, это частично просто теоретический вопрос любопытства.

6
задан Brad Robinson 1 July 2010 в 12:21
поделиться

2 ответа

30к - это не то, что я считаю большим. Прежде чем волноваться, я должен был профилировать. Индексатор должен быть прекрасным для наилучшего баланса гибкости и безопасности.

Например, чтобы создать строку размером 128 КБ (и отдельный массив того же размера), заполните ее мусором (включая время обработки Random ) и просуммируйте все кодовые точки символов с помощью индексатор занимает ... 3 мс:

        var watch = Stopwatch.StartNew();
        char[] chars = new char[128 * 1024];
        Random rand = new Random(); // fill with junk
        for (int i = 0; i < chars.Length; i++) chars[i] =
             (char) ((int) 'a' + rand.Next(26));

        int sum = 0;
        string s = new string(chars);
        int len = s.Length;
        for(int i = 0 ; i < len ; i++)
        {
            sum += (int) chars[i];
        }
        watch.Stop();
        Console.WriteLine(sum);
        Console.WriteLine(watch.ElapsedMilliseconds + "ms");
        Console.ReadLine();

Для файлов, которые на самом деле большие, следует использовать подход читателя - StreamReader и т. д.

2
ответ дан 17 December 2019 в 18:09
поделиться

«Парсинг» - неточный термин. Поскольку вы говорите о 30k, кажется, что вы имеете дело с какой-то структурированной строкой, которую можно покрыть, создав синтаксический анализатор с помощью инструмента генератора синтаксического анализатора.

Хорошим инструментом для создания, поддержки и понимания всего процесса является система анализа GOLD от Девина Кука: http://www.devincook.com/goldparser/

Это может помочь вам создать код, который эффективный и правильный для многих нужд текстового синтаксического анализа.

Что касается ваших замечаний:

  1. обычно бесполезен для синтаксического анализа, который идет дальше разделения строки.

  2. лучше подходит, если нет рекурсий или слишком сложных правил.

  3. - это просто запрет, если вы действительно не определили это как серьезную проблему. JIT может выполнять проверки диапазона только тогда, когда это необходимо, и действительно для простых циклов (типичный цикл for ) это выполняется довольно хорошо.

1
ответ дан 17 December 2019 в 18:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: