提高Boost正则表达式的速度或在C++中使用PCRE



你好,这是我的字符串:

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"}')}
..
..
..

现在,我想使用regex

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

(将每条线路(其他线路)放入

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

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

我很惊讶,但这次很糟糕。10 Min正则表达式得到所有行(检测)后

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

在Boost或标准C++正则表达式中是否有任何方法可以提高速度(在3-10秒内完成),或者我必须在C++项目中只使用PCRE

结果

Regex:10分钟
增压:2分钟
Pcre(PHP):3秒

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

你必须让我相信这一点!!

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

该基准测试软件的问题是,您可以使用单个测试线
运行一百万次,这与一百万条线路运行一次是一样的。

以下是结果,你可以自己尝试一下
基本上,它只需2.5秒就可以全面运行。

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

目标行:

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

1线路运行1000000次:

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

10000条线路运行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条线路运行9999000次:

 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

根据regex101.com,需要610步才能将正则表达式与5行进行匹配。太多了。

如果将(.*?)更改为([^}]*),则需要230个步骤。这样可以将时间缩短到5分钟以内。

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

如果你去掉整个表情周围的捕捉组,我可以省去10个步骤。你不需要它,$0是等价的。

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

如果不更好地了解数据可以包含什么,就很难知道什么可以优化。


您可以考虑的另一件事是使用将regex中完成的一些工作移动到C++。

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

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

最新更新