C # Ускорение парсера с константами? Абстрактный класс хотя - PullRequest
1 голос
/ 18 мая 2011

У меня есть серия синтаксических анализаторов, которые анализируют один и тот же базовый вид текста для соответствующих данных, но они поступают из разных источников, поэтому они отличаются от других.Я анализирую миллионы документов в день, поэтому любая оптимизация скорости помогает.

Вот упрощенный пример, демонстрирующий фундаментальную проблему.Синтаксический анализатор настроен таким образом, что существует базовый абстрактный синтаксический анализатор, который реализуют фактические синтаксические анализаторы:

abstract class BaseParser
{
     protected abstract string SomeRegex { get; }

     public string ParseSomethingCool(string text)
     {
         return Regex.Match(text, SomeRegex).Value;
     }

     ....
 }

 class Parser1: BaseParser
 {
     protected override string SomeRegex { get { return "^.*"; } } // example regex

     ...
 }

 class Parser2: BaseParser
 {
     protected override string SomeRegex { get { return "^[0-9]+"; } } // example regex

     ...
 }

Итак, мои вопросы:

  • Если бы я должен был вернуть вещи вбы получить константы ускорения?
  • Теоретически, если бы оно не использовало свойство, и все было бы прямой константой, ускорило бы это еще больше?
  • Какая скорость увеличивается, есличто я могу увидеть?
  • Я просто цепляюсь за соломинку?

Ответы [ 4 ]

2 голосов
/ 18 мая 2011

Я не думаю, что преобразование свойств в константы даст вам заметный прирост производительности. Код Jit'а, вероятно, в любом случае имеет встроенный код (поскольку вы вводите константы).

Я думаю, что лучший подход - это сначала профилировать ваш код и посмотреть, какие части обладают наибольшим потенциалом оптимизации. Мое предложение вещей, чтобы посмотреть:

  1. RegEx - как вы уже знаете, иногда хорошо сконструированное выражение RegEx объясняет разницу между быстрым и чрезвычайно медленным. Это зависит от случая к случаю, в зависимости от используемого выражения и используемого вами текста.
  2. Альтернативы - я не уверен, какой тип соответствия вы выполняете, но, возможно, стоит рассмотреть другие подходы, особенно если то, что вы пытаетесь сопоставить, не так сложно. Затем сравните результаты.
  3. Другие части вашего кода - посмотрите, где находится горлышко бутылки. Это на диске IO или CPU? Посмотрите, помогут ли другие потоки, или, возможно, вернитесь к функции, которая читает содержимое файла.

Что бы вы ни делали в конечном итоге, это всегда большая помощь для измерения. Определите области, где есть возможность, найдите более быстрый способ сделать это, затем повторите измерения, чтобы проверить, действительно ли это быстрее.

1 голос
/ 18 мая 2011

Не думаю, что вы заметите заметное улучшение скорости от такого рода преследований. Однако лучше всего попробовать и сравнить результаты.

Одно изменение, которое будет иметь значение, - это не использовать Regex, если вы можете обойтись без него. Regex - довольно большой и полезный молоток, но не каждому гвоздю нужен такой большой молоток.

1 голос
/ 18 мая 2011

Вещи в get уже постоянны.

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

0 голосов
/ 18 мая 2011

Из кода вы показываете непонятно, зачем вам нужен абстрактный класс и наследование.
Использование виртуальных членов медленнее.Кроме того, ваши дочерние классы не запечатаны.

Почему бы вам не сделать что-то вроде этого:

public class Parser
{
    private Regex regex;

    public Parser(string someRegex)
    {
        regex = new Regex(someRegex, RegexOptions.Compiled);
    }

    public string ParseSomethingCool(string text)
    {
        return regex.Match(text).Value;
    }
}

или как это

public static class Parser
{
    public static string ParseSomethingCool(string text, string someRegex)
    {
        return Regex.Match(text, someRegex).Value;
    }
}

Однако яПодумайте, наибольший прирост производительности вы бы достигли, если бы использовали многопоточность.Вероятно, вы уже делаете.Если вы не посмотрите на Task Parallel Library

...