10 Star 5 Fork 7

openEuler/re2-rust

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README

re2-rust

re2-rust介绍

re2-rust是用来兼容RE2 API(version 2021-11-01)的项目,通过调用Rust正则表达式库进行实现。re2-rust的功能与原本RE2基本保持一致。

re2-rust保留了re2中的对外的接口,分别在re2.h、set.h和filtered_re2.h中。

re2.h中的接口可以实现正则表达式的匹配、查找和替换的功能;set.h中的接口可以同时处理多组正则表达式;filtered_re.h中的接口提供了一种预过滤机制,有助于减少需要实际搜索的regexp的数量。这些接口再调用Rust正则库中提供的接口对用户传递过来的数据进行处理,最后再把结果进行返回。

编译、安装re2-rust

$ git clone https://gitee.com/openeuler/re2-rust.git
$ cd re2-rust

使用openEuler 22.03-LTS

dnf install git
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
dnf install g++
git clone https://gitee.com/openeuler/re2-rust.git
cd re2-rust
make
make install
make test
g++ testinstall.cc -o testinstall -lre2
./testinstall

使用Ubuntu 20.04

$ make
$ sudo make install
$ make test
$ g++ testinstall.cc -o testinstall -lre2
$ ./testinstall

性能测试

RE2-Rust项目中只需要对re2目录下filtered_re2.h、re2.h、set.h文件中声明的部分函数进行性能测试,而filtered_re2.h中的主要函数是通过调用re2.h中的PartialMatch()函数实现的,所以下面只对re2.h和set.h文件中主要函数进行性能测试。相关的性能测试代码详见regexp_benchmark.cc文件。 re2.h文件中相关函数的性能测试: 我们对re2.h对外接口中的FullMatch()PartialMatch()FindAndConsume()三个函数进行了测试,下面表格中的re2-c++和re2-rust分别通过上述三个函数测试了表格中的八个正则表达式,但由于这三个函数的本质是调用了RE2::DoMatch()函数,所以在表格中不对上面三个函数进行区分。下面表格是regexp_benchmark.cc中一些正则表达式在text_re2_1KB.txt文本下的执行时间。

正则表达式 (含义) RE2-C++ RE2-Rust PCRE Regex
“” 339 ns/iter 213 ns/iter 133 ns/iter 54 ns/iter
3019.80 MB/s 4785.82 MB/s 7653.53 MB/s 18890.09 MB/s
"abcdefg" 820 ns/iter 259 ns/iter 1686 ns/iter 97 ns/iter
匹配abcdefg字符串 1248.70 MB/s 3951.78 MB/s 607.26 MB/s 10507.00 MB/s
`"(?-s)^(?:GET POST) +([^ ]+) HTTP"` 343 ns/iter 246 ns/iter 147 ns/iter
匹配HTTP请求报文格式 2982.79 MB/s 4157.21 MB/s 6932.47 MB/s 11096.98 MB/s
"(?-s)^(.+)" 542 ns/iter 212 ns/iter 203 ns/iter 56 ns/iter
匹配行首连续出现一次以上的字符 1886.72 MB/s 4807.80 MB/s 5031.92 MB/s 18062.85 MB/s
"(?-s)^([ -~]+)" 557 ns/iter 217 ns/iter 190 ns/iter 59 ns/iter
匹配行首连续出现一次以上的ASCII字符 1835.28 MB/s 4715.87 MB/s 5365.38 MB/s 17188.64 MB/s
"(?s).*" 349 ns/iter 21223 ns/iter 154 ns/iter 2588 ns/iter
匹配任意字符 2929.63 MB/s 48.25 MB/s 6640.02 MB/s 395.62 MB/s
"(?s).*$" 11401 ns/iter 19678 ns/iter 159 ns/iter 2468 ns/iter
匹配任意字符 89.81 MB/s 52.04 MB/s 6415.22 MB/s 414.86 MB/s
"(?s)((.*)()()($))" 11179 ns/iter 19873 ns/iter 260 ns/iter 2488 ns/iter
匹配任意字符 91.59 MB/s 51.53 MB/s 3937.18 MB/s 411.54 MB/s

注:(?s)表示单行模式

set.h文件中相关函数的性能测试:

可以看到,set.h中主要是下面的函数接口有匹配功能:

bool Match(const StringPiece& text, std::vector* v) const;

上述函数功能为同一文本可同时匹配多个正则表达式,并将匹配到的结果保存到向量v中,若传入的v为空则表示不需要返回匹配结果。

我们使用的待匹配文本还是text_re2_1KB.txt中的数据,同时匹配五个正则表达式,分别是"(?s).*""(?s).*""(?s)((.*)()()(""(?*s*)((.∗)()()())""hwx""ldi"

由于对于锚点为RE2::UNANCHOREDRE2::ANCHOR_BOTHRE2::ANCHOR_START三种不同情况已经在RE2::Set::Add()已经进行了处理,所以对锚点三种不同情况的处理并不计算在匹配时间。为方便RE2-Rust与RE2-C++、Regex进行性能对比分析,我们采用锚点为RE2::UNANCHORED进行性能对比,详细性能评测代码见regexp_benchmark.cc文件中Set_Match_UNANCHORED_RE2()Set_Match_UNANCHORED_NULL_RE2()函数。下面是set.h文件中RE2::Set::Match()在RE2-C++、RE2-Rust、Regex三种不同正则表达式框架下的性能对比结果(PCRE不支持同时匹配多个正则表达式):

RE2-C++ RE2-Rust Regex
V为空 1716 ns/iter 383 ns/iter 18 ns/iter
596.67 MB/s 2671.52 MB/s 56944 MB/s
V不为空 8231 ns/iter 535 ns/iter 6686 ns/iter
124.40 MB/s 1910.52 MB/s 153 MB/s

另外我们采用第三方正则表达式测试框架regex-performance,通过一些指定的正则表达式,对主流的正则表达式库进行了评测(测试详情可见https://gitee.com/openeuler/re2-rust/blob/master/test-results.txt),得到了如下结果:

Total Results:
[      ctre] time:  4010462.7 ms, score:      6 points,
[     boost] time:  2010606.4 ms, score:      3 points,
[    cppstd] time:  3118716.6 ms, score:      0 points,
[      pcre] time:  32853.7 ms, score:      4 points,
[  pcre-dfa] time:  22640.6 ms, score:      5 points,
[  pcre-jit] time:    851.1 ms, score:     45 points,
[       re2] time:    516.4 ms, score:     42 points,
[      onig] time:  43648.0 ms, score:      6 points,
[       tre] time:   9306.2 ms, score:      0 points,
[     hscan] time:    382.4 ms, score:     69 points,
[      yara] time:  2001920.1 ms, score:     13 points,
[  re2-rust] time:   4937.7 ms, score:     44 points,
[rust_regex] time:   4790.2 ms, score:     56 points,
[rust_regrs] time:  47772.1 ms, score:      6 points,

从以上测试结果看re2-rust评分比re2略高,但是耗时re2-rust比re2增加很多,通过仔细分析发现正则表达式'[a-q][^u-z]{13}x'耗时特别高4280.7 - 130.5 = 4150.2 ms,另外'\b\w+nn\b'耗时322.6 - 23.9 = 298.7,除去这两个异常测试项外的16个测试项耗时re2-rust:334.4 ms vs. re2: 362 ms ,也就是说re2-rust在大多数情况下性能比re2要好。 从测试耗时看re2-rust和rust_regex两者相差3%(多次测评结果看两者差距上下浮动5%以内),总体看re2-rust和rust_regex性能基本一致。 综合对比可知:

  1. RE2-Rust在大部分测试用例下性能优于RE2-C++,而在涉及到捕获组会差于RE2-C++,原因可见https://github.com/rust-lang/regex/discussions/903
  2. RE2-rust和Regex性能大致相当,但是由于RE2-Rust是调用了Regex的对外的C接口,所以RE2-rust会比Regex多了函数调用开销、特殊处理、错误判断等开销,故RE2-Rust性能会略低于Regex
  3. RE2-Rust支持多行模式,但不支持同名的捕获组
  4. RE2-Rust比RE2-C++支持更少的转义字符,比如”\C”

Links

空文件

简介

a compatible RE2 API by calling Rust library regex(rure) 展开 收起
取消

发行版 (1)

全部
2年前

贡献者

全部

近期动态

不能加载更多了
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/openeuler/re2-rust.git
git@gitee.com:openeuler/re2-rust.git
openeuler
re2-rust
re2-rust
master

搜索帮助

371d5123 14472233 46e8bd33 14472233