c++ - 正则表达式慢

标签 c++ regex visual-c++ c++11 visual-studio-2012

我正在尝试使用正则表达式解析构建日志文件以获取一些信息。我正在尝试使用像 ("( {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 uniquley - ("(.+)(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;

输出:

Time taken for parsing first log = 119416 ms lines = 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;

输出:

Time taken for parsing first log = 131613 ms lines = 9216

为什么第二种情况需要更多时间?

最佳答案

So why the does not go at least some amount lower when I removed half of the lines.

Why its taking more time in the second case ?

可以想象,regex 库能够以某种方式比大小检查更有效地过滤行。也有可能在 while 循环中引入额外的分支会混淆编译器的分支预测,因此您无法获得最佳的指令流水线/预取。

Also, can anyone tell me what kind of regular expression is faster, more generic one or more specific one.

如果表达式 ("(.+)(c1xx.dll)(.+)") 有效,我相信 (".+c1xx\\.dll.+") 也可以工作,并且正则表达式不会为您保存匹配位置。

关于c++ - 正则表达式慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11148488/

相关文章:

c++ - `std::string(*)(int)` 中的星号(*)代表什么

c++ - std::thread::join 在析构函数中挂起

regex - 使用 XPath 1.0,如何让多个匿名函数对提取的内容进行操作?

python - 从 python 文件中读取特定字符串?

c++ - 64 位应用程序和内联汇编

visual-c++ - 转换为 COFF 时失败 : file invalid or corrupt

c++ - 从 Char 数组中删除前两个字符

c++ - 如何定义存在于不同文件中的同名函数

regex - sed 正则表达式提取字段并构建新的

c++ - 双重检查线程安全单例和无锁的创建