Boost Xpressive - почему случай сбоя этого регулярного выражения экспоненциальный?

Я использую простое регулярное выражение для сопоставления со строкой, прочитанной из ОС, которая имеет следующий формат:

отметка времени:{список значений через запятую}

Где отметка времени не подписана, значения не подписаны

Для этого я использовал следующее регулярное выражение, используя boost::xpressive

std::vector< uint32_t > idleReports;
uint32_t timestamp = 0;

sregex cpuIdleVal = ( +_d )[ push_back( xp::ref( idleReports ), as<unsigned>( _ ) ) ];
sregex cpuIdleData = cpuIdleVal >> "," | cpuIdleVal;
sregex fullMatch = ( +_d )[ xp::ref( timestamp ) = as<unsigned>( _ ) ] 
                                 >> ":" >> +cpuIdleData;
smatch what;
if( regex_match( test, what, fullMatch ) )
{
   // stuff
}

Все отлично работает в случае успеха, бенчмаркинг показывает, что регулярное выражение занимает около 80 мксек, чтобы соответствовать следующей строке:

"1381152543:988900,987661,990529,987440,989041,987616,988185,988346,968859,988919,859559,988967,991040,988942"

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

Если значение 5 является отрицательным, время, затрачиваемое еще

Почему производительность так плохо для случаев отказа?

Я исправил проблему, изменив исходное регулярное выражение на:

sregex cpuIdleData = "," >> cpuIdleVal;
sregex fullMatch =  ( +_d )[ xp::ref( timestamp ) = as<unsigned>( _ ) ] 
                           >> ":" >> cpuIdleVal >> -+ cpuIdleData ;

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

В измененной версии сценарии сбоев работают так же хорошо (или немного лучше) сценариев успеха.

0 ответов

Другие вопросы по тегам