1

次の形式を持つOSから読み取った文字列と照合するために、単純な正規表現を使用しています。

タイムスタンプ:{コンマ区切りの値のリスト}

タイムスタンプが符号なしの場合、値は符号なしです

これを行うには、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 ;

つまり、コンマ区切りのリストに対して非貪欲な一致を作成します。

変更されたバージョンでは、失敗のシナリオは成功のシナリオと同じくらい (またはわずかに優れています) 実行されます。

4

0 に答える 0