【问题标题】:Increase Boost regex speed or use PCRE in C++ [duplicate]提高 Boost 正则表达式速度或在 C++ 中使用 PCRE [重复]
【发布时间】:2016-08-09 10:09:10
【问题描述】:

你好,这是我的字符串:

key{info('1'),details('1'),others('{"1": "2test data1", "2": "2test data2"}')}

我制作了超过 100 万条这条线,并将它们放在一个类似(相同)的文件中

key{info('1'),details('1'),others('{"1": "2test data1", "2": "2test data2"}')}
key{info('1'),details('1'),others('{"1": "2test data1", "2": "2test data2"}')}
key{info('1'),details('1'),others('{"1": "2test data1", "2": "2test data2"}')}
key{info('1'),details('1'),others('{"1": "2test data1", "2": "2test data2"}')}
key{info('1'),details('1'),others('{"1": "2test data1", "2": "2test data2"}')}
..
..
..

现在,我想使用正则表达式

key[{]info[(][']1['][)],details[(][']1['][)],others[(]['][{](.*?)[}]['][)][}]

(获取每一行(其他)里面)

我在 PHP 中使用preg_match_all 函数对其进行了测试,我很惊讶 PHP 在 3 秒 内检测到所有 100 万行,但我真正的程序是用 C++ 编写的,所以我尝试了这个正则表达式在 C++ 上

regex RegexString(R"~(key[{]info[(][']1['][)],details[(][']1['][)],others[(]['][{](.*?)[}]['][)][}])~", regex_constants::optimize);

我很惊讶,但这次很糟糕。在10 Min regex 得到所有行之后(检测)

我使用了 Boost 并获得了更好的结果(2 分钟),但是我在 PHP (PCRE) 中看到的(3 秒)让我抓狂......现在,我该怎么办?

在 Boost 或标准 C++ 正则表达式中有什么方法可以提高速度(在 3-10 秒内完成)还是我必须在我的 C++ 项目中使用 PCRE?

结果

正则表达式:10 分钟
提升:2 分钟
Pcre(PHP) : 3 秒

【问题讨论】:

  • 没有帮助!!!我只是想知道我是否可以在 boost 中优化这个正则表达式请告诉我什么是最好的优化或者如果没有办法提高速度我将使用 pcre
  • 您确定时差是正则表达式的结果而不是其他原因吗?您是在循环内编译正则表达式还是什么?
  • @Elh48 你能不能别喊“!!!”
  • 你能告诉我你想从样本输入中提取的确切内容吗?我将向您展示一种可能更快的方法。

标签: c++ regex boost pcre


【解决方案1】:

i used the boost and got better result (2 Min)

你必须让我相信它!

使用此应用程序RegexFormat 中的使用 Boost 的基准测试软件,我得到的时间不到 3 秒。

benchmark software 的问题是您可以使用一条测试线
并运行它一百万次,它与运行它一次的一百万行相同。

这是结果,您可以自己尝试一下。
基本上,它在 2.5 秒内全面运行。

测试了两个正则表达式,一个带有额外的捕获组,一个没有,
代表您上面的双重正则表达式文本。

目标行:

key{info('1'),details('1'),others('{"1": "2test data1", "2": "2test data2"}')}

1 行运行 1,000,000 次:

Regex1:   key[{]info[(][']1['][)],details[(][']1['][)],others[(]['][{](.*?)[}]['][)][}]
Options:  < none >
Completed iterations:   1000  /  1000     ( x 1000 )
Matches found per iteration:   1
Elapsed Time:    2.78 s,   2777.70 ms,   2777696 µs


Regex2:   (key[{]info[(][']1['][)],details[(][']1['][)],others[(]['][{](.*?)[}]['][)][}])
Options:  < none >
Completed iterations:   1000  /  1000     ( x 1000 )
Matches found per iteration:   1
Elapsed Time:    2.89 s,   2893.58 ms,   2893576 µs

1000 行运行 1000 次:

Regex1:   key[{]info[(][']1['][)],details[(][']1['][)],others[(]['][{](.*?)[}]['][)][}]
Options:  < none >
Completed iterations:   1  /  1     ( x 1000 )
Matches found per iteration:   1000
Elapsed Time:    2.38 s,   2381.16 ms,   2381163 µs


Regex2:   (key[{]info[(][']1['][)],details[(][']1['][)],others[(]['][{](.*?)[}]['][)][}])
Options:  < none >
Completed iterations:   1  /  1     ( x 1000 )
Matches found per iteration:   1000
Elapsed Time:    2.50 s,   2495.65 ms,   2495649 µs

10,000 行运行 100 次:

Regex1:   key[{]info[(][']1['][)],details[(][']1['][)],others[(]['][{](.*?)[}]['][)][}]
Options:  < none >
Completed iterations:   100  /  100     ( x 1 )
Matches found per iteration:   10000
Elapsed Time:    2.38 s,   2384.73 ms,   2384729 µs


Regex2:   (key[{]info[(][']1['][)],details[(][']1['][)],others[(]['][{](.*?)[}]['][)][}])
Options:  < none >
Completed iterations:   100  /  100     ( x 1 )
Matches found per iteration:   10000
Elapsed Time:    2.50 s,   2497.35 ms,   2497349 µs

最后,进行一次落水测试。 1 线运行 9,999,000 次:

 Regex1:   key[{]info[(][']1['][)],details[(][']1['][)],others[(]['][{](.*?)[}]['][)][}]
Options:  < none >
Completed iterations:   9999  /  9999     ( x 1000 )
Matches found per iteration:   1
Elapsed Time:    27.54 s,   27536.56 ms,   27536560 µs


Regex2:   (key[{]info[(][']1['][)],details[(][']1['][)],others[(]['][{](.*?)[}]['][)][}])
Options:  < none >
Completed iterations:   9999  /  9999     ( x 1000 )
Matches found per iteration:   1
Elapsed Time:    28.73 s,   28726.18 ms,   28726182 µs

【讨论】:

  • @Elh48 - boost::regex 基准测试使用您的正则表达式匹配您的行,100 万次,耗时 2 秒,正盯着您的脸。我猜你不知道自己在做什么。
  • @Elh48 停止骚扰“!!!!!!!??????”。在被反复询问后,您未能显示您的代码。你总是难以置信地大喊大叫。我得出的结论是你不想被帮助,而且你是个巨魔。
【解决方案2】:

根据regex101.com,将您的正则表达式与 5 行匹配需要 610 个步骤。太多了。

(.*?) 更改为([^}]*) 需要230 步。这应该会将时间缩短到不到 5 分钟。

如果您的表达式中可能包含 }s,而 ([^}]*) 将无法匹配,请尝试使用 ((?:[^}]*}??)*?)。它增加了 25-40 步,但可能没有你原来的那么慢。

如果您删除整个表达式周围的捕获组,我可以减少 10 个步骤。你不需要它,$0 是等价的。

您需要了解的是,C++ 使用与 PCRE 不同的正则表达式引擎。 PCRE 非常先进,可能包含更多优化。

如果不更好地了解您的数据可以包含哪些内容,就很难知道可以优化哪些内容。


您可以考虑的另一件事是将正则表达式中完成的一些工作转移到 C++。

例如,您可以尝试查找 key{info(' 的所有实例并从您的正则表达式的开头删除 key[{]info[(][']。然后,您可以尝试查看是否可以在每次出现 key{info(' 之后直接进行匹配。

更好的是,为什么不将所有}')}s 替换为该行中其他任何地方都不会出现的字符,然后使用([^c]*) 而不是(.*?)[}]['][)][}]

【讨论】:

  • @Elh48 您的数据能否在$2 中包含}s?如果答案是否定的,添加它不会破坏正则表达式。
  • 是可能包含 } !!!而且我根本不能使用启动器..我有线条,而且..我必须得到所有..这个正则表达式在 php 中在 3 秒内工作!我不知道为什么我必须在 c++ boost 中等待 2-3 分钟!!!!!!!
  • @Elh48 我几乎听不懂你在说什么。您所说的“启动器”是什么意思?
  • @Elh48 你没有向我们展示任何代码,所以我们不可能知道它为什么运行这么慢(“!!!”)
  • 我将使用 pcre 因为它更快,而且我得到了 1 秒 (哇) ((?:[^}]*}??)*?) ... 谢谢伙计,但如果你知道更好的请告诉我
猜你喜欢
  • 2021-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
相关资源
最近更新 更多