2014-10-09 4 views
1

я следующее:Матч СТРОКА против большого списка регулярных выражений, производительности в Java

private static List<Pattern> pats; 

Этот список содержит около 90 моделей, которые инстанцированы перед тем итерации. Шаблоны являются сложными, как:

System.out.println("pat: " + pats.get(0).toString()); 

// pat: \bsingle1\b|\bsingle2\b|(?=.*\bcombo1\b)(?=.*\bcombo2\b)|\bsingle3\b|\bwild.*card\b ... 

Некоторые из образцов содержат около 40-50 отдельных слов или сочетания слов, как регулярное выражение выше шоу. Слова могут содержать подстановочные знаки.

Теперь у меня есть список строк, предложений по 30-60 символов. Я повторяю их и для каждой строки в списке, я повторяю их через список шаблонов и выполняю pattern.match("This is one of the strings in my list").find(), пока не получу совпадение, которое я отмечаю и сохраняю где-то в другом месте, затем я выхожу из итерации через шаблоны и продолжаю следующую строку в списке.

Это задание на категоризацию, поэтому несколько строк могут совпадать по одному шаблону.

Моя проблема заключается в том, что это, конечно, требует много времени выполнения, я ищу более эффективный способ решить эту проблему.

Любые предложения?

+0

Я думаю, что вы можете искать что-то вроде [алгоритм Ахо-Corasick] (https://en.wikipedia.org/wiki/Aho % E2% 80% 93Corasick_string_matching_algorithm). –

+0

Вы можете попытаться оптимизировать свои регулярные выражения, это хорошая статья на нем. http://stackoverflow.com/questions/1252194/regex-performance-optimization-tips-and-tricks –

+0

Я не думаю, что Aho-Corasick algoritm поддерживает подстановочные знаки, но это было интересно, и я нашел несколько реализаций, заметьте для себя для будущих потребностей. – Wrench

ответ

0

Одна вещь, которая решила мою проблему (до 90%), заключалась в том, чтобы частично отказаться от регулярного выражения, где String.indexOf() сделал больше смысла с точки зрения производительности.

Это сообщение вдохновило меня: Quickest way to return list of Strings by using wildcard from collection in Java

я написал свою собственную реализацию, так как один в ссылке обрабатывает только полные слова, в то время как я имею дело с предложениями.

Это помогло с подстановочными знаками «*» и трубами «hel (l | lo)» в перспективе производительности, причем первое больше, чем последнее.

Причиной для этого направления было несколько рекомендаций, и он улучшил производительность, сократив время на 200000 предложений с 1,5 часов до 15 минут.

0

Вы также можете разгрузить регулярное выражение в специальном сервисе? Я считаю, что это может быть быстрее (и, возможно, безопаснее), чем частично отказаться от регулярного выражения?

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

Вот пример такой реализации через REST API: http://www.rex-daemon.com/tutorial/more-advanced-queries/

Смежные вопросы