我正在使用一个简单的正则表达式来匹配从具有以下格式的操作系统读取的字符串:
时间戳:{逗号分隔的值列表}
其中 时间戳是未签名的 值是未签名的
要做到这一点,我使用了以下正则表达式使用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
}
对于成功案例一切正常,基准测试显示正则表达式大约需要80usec来匹配以下字符串:
"1381152543:988900,987661,990529,987440,989041,987616,988185,988346,968859,988919,859559,988967,991040,988942"
如果输入字符串在其中一个值中包含负值,性能会显着下降,那么如果值4为负,则正则表达式需要13秒才能报告失败。
如果value5为负数,则所用时间会更长。
为什么失败案例的表现如此糟糕?
我已通过将原始正则表达式更改为:
来解决此问题sregex cpuIdleData = "," >> cpuIdleVal;
sregex fullMatch = ( +_d )[ xp::ref( timestamp ) = as<unsigned>( _ ) ]
>> ":" >> cpuIdleVal >> -+ cpuIdleData ;
即。使得逗号分隔列表的匹配非贪婪。
在更改后的版本中,失败场景的表现与成功场景一样好(或略好)。