2

正規表現を使用して、ビルド ログ ファイルを解析して情報を取得しようとしています。("( {9}time)(.+)(c1xx\\.dll+)(.+)s")次のような行に一致するように正規表現を使用しようとしていますtime(D:\Program Files\Microsoft Visual Studio 11.0\VC\bin\c1xx.dll)=0.047s

これは、19,000 行のファイルで、完了するのに約 120 秒かかります。そのうちのいくつかはかなり大きいです。基本的な問題は、いくつかの条件を使用して行数を約 19000 に減らしたとき、何も変わらず、実際に悪化したことです。わかりません。正規表現を完全に削除すると、ファイルのスキャンだけで約 6 秒かかります。つまり、ここでは正規表現が時間のかかる主なプロセスです。では、行の半分を削除したときに、少なくともいくらか下がらないのはなぜですか。

また、どのような正規表現がより高速で、より一般的であるか、またはより具体的なものであるかを誰かに教えてもらえますか。つまりtime(D:\Program Files\Microsoft Visual Studio 11.0\VC\bin\c1xx.dll)=0.047s、この正規表現も使用して、ファイル内のこの行を一意に一致させることができます("(.+)(c1xx.dll)(.+)")。しかし、全体の実行がさらに遅くなりますが、次のようなものを使用("( {9}time)(.+)(c1xx\\.dll+)(.+)")すると、実行がわずかに速くなります。

私はC++ 11正規表現ライブラリと主にregex_match関数を使用しています。

regex c1xx("( {9}time)(.+)(c1xx\\.dll+)(.+)s");
auto start = system_clock::now();
int linecount = 0;
while (getline(inFile, currentLine))
{
    if (regex_match(currentLine.c_str(), cppFile))
    {
        linecount++;
        // Do something, just insert it into a vector
    }
}

auto end = system_clock::now();
auto elapsed = duration_cast<milliseconds>(end - start);
cout << "Time taken for parsing first log = " << elapsed.count() << " ms" << " lines = " << linecount << endl;

出力:

最初のログの解析にかかった時間 = 119416 ms 行 = 19617

regex c1xx("( {9}time)(.+)(c1xx\\.dll+)(.+)s");
auto start = system_clock::now();
int linecount = 0;
while (getline(inFile, currentLine))
{
    if (currentLine.size() > 200)
    {
        continue;
    }

    if (regex_match(currentLine.c_str(), cppFile))
    {
        linecount++;
        // Do something, just insert it into a vector
    }
}

auto end = system_clock::now();
auto elapsed = duration_cast<milliseconds>(end - start);
cout << "Time taken for parsing first log = " << elapsed.count() << " ms" << " lines = " << linecount << endl;

出力:

最初のログの解析にかかった時間 = 131613 ms 行 = 9216

2番目のケースで時間がかかるのはなぜですか?

4

1 に答える 1

2

では、行の半分を削除したときに、少なくともいくらか下がらないのはなぜですか。

2番目のケースで時間がかかるのはなぜですか?

regexライブラリは、サイズ チェックよりも効率的に行を除外できると考えられます。また、while ループに追加の分岐を導入すると、コンパイラの分岐予測が混乱し、最適な命令パイプライン/プリフェッチが得られない可能性もあります。

また、どのような正規表現がより高速で、より一般的であるか、またはより具体的なものであるかを誰かに教えてもらえますか。

("(.+)(c1xx.dll)(.+)")がうまくいくなら、私はそれもうまくいくと信じて(".+c1xx\\.dll.+")おり、正規表現はマッチ位置を保存することを気にしません.

于 2012-06-22T02:23:20.710 に答える