У меня есть большое и сложное регулярное выражение С#, которое работает нормально при интерпретации, но немного медленнее. Я пытаюсь ускорить это, установив RegexOptions.Compiled
, и это, кажется, занимает около 30 секунд в первый раз и сразу после этого. Я пытаюсь это отрицать, сначала компилируя регулярное выражение на сборку, поэтому мое приложение может быть как можно быстрее.
Моя проблема в том, когда происходит компиляция, независимо от того, скомпилирована ли она в приложении:
Regex myComplexRegex = new Regex(regexText, RegexOptions.Compiled);
MatchCollection matches = myComplexRegex.Matches(searchText);
foreach (Match match in matches) // <--- when the one-time long delay kicks in
{
}
или с помощью команды Regex.CompileToAssembly:
MatchCollection matches = new CompiledAssembly.ComplexRegex().Matches(searchText);
foreach (Match match in matches) // <--- when the one-time long delay kicks in
{
}
Это делает сборку на сборке практически бесполезной, так как я все еще получаю задержку при первом вызове foreach
. Я хочу, чтобы вся компиляция была выполнена во время компиляции (при вызове Regex.CompileToAssembly), а не во время выполнения. Где я ошибаюсь?
(Код, который я использую для компиляции в сборку, похож на http://www.dijksterhuis.org/regular-expressions-advanced/, если это актуально).
Edit:
Должен ли я использовать new
при вызове скомпилированной сборки в new CompiledAssembly.ComplexRegex().Matches(searchText);
? Он дает ошибку "ссылка на объект" без него.
Обновление 2
Спасибо за ответы/комментарии. Регулярное выражение, которое я использую, довольно длинное, но в основном прямолинейное, список тысяч слов, каждый из которых разделен символом |. Я не вижу, чтобы это было проблемой возврата. Строка subject может быть длиной всего одна буква, и она все равно может привести к задержке компиляции. Для регулярного выражения RegexOptions.Compiled это займет более 10 секунд, чтобы выполнить, когда регулярное выражение содержит 5000 слов. Для сравнения, не скомпилированная версия регулярного выражения может принимать 30 000 слов и выполнять их практически мгновенно.
После проведения большого количества тестов на этом, я думаю, что я узнал:
- Не используйте RegexOptions.Compiled, когда ваше регулярное выражение имеет много альтернатив - его можно очень медленно компилировать.
- .Net будет использовать ленивую оценку для regex, когда это возможно, и AFAI может видеть, что это расширяет (по крайней мере до некоторой степени) компиляцию регулярных выражений, Регулярное выражение будет полностью скомпилировано только тогда, когда оно должно быть, и, похоже, не существует способа форсировать компиляцию раньше времени.
- Regex.CompileToAssembly была бы намного более полезна, если бы регулярные выражения могли быть полностью скомпилированы, кажется, что они не имеют смысла, поскольку они являются бессмысленными.
Пожалуйста, поправьте меня, если я ошибаюсь или что-то не хватает!