4nt*_*ine 3 regex serialization rust deserialization
我正在开发一些性能至关重要的应用程序,我正在寻找改进它的机会。该应用程序广泛使用正则表达式(regex crate),例如:
use regex::Regex;
...
let Regex = Regex::new(r###"[a-z0-9%]{3,}"###).unwrap();
Run Code Online (Sandbox Code Playgroud)
有没有机会将预编译的Regex实例保存到缓冲区(想想Vec<u8>)并在以后加载预编译以避免多次编译(在文档中看不到任何类似的东西)?
附注。我已经懒惰地这样做了:
lazy_static! {
static ref REGEX2: Regex = Regex::new(r###"[a-z0-9%]{3,}"###).unwrap();
}
Run Code Online (Sandbox Code Playgroud)
如果有多次调用,则尝试节省一些 CPU 周期(但那是另一回事)。
附注。出于好奇,我对代码进行了基准测试:
fn bench_regex_candidates(b: &mut Bencher) {
b.iter(|| {
Regex::new(r###"[a-z0-9%]{3,}"###).unwrap();
});
}
fn bench_regex_content(b: &mut Bencher) {
b.iter(|| {
Regex::new(r###"^([^*|@"!]*?)#([@?$])?#(.+)$"###).unwrap()
});
}
Run Code Online (Sandbox Code Playgroud)
并且编译速度很快(相对于我的需要):
regex/candidates time: [22.021 us 22.684 us 23.689 us]
Found 11 outliers among 100 measurements (11.00%)
2 (2.00%) high mild
9 (9.00%) high severe
regex/content time: [36.542 us 36.687 us 36.845 us]
Found 8 outliers among 100 measurements (8.00%)
3 (3.00%) high mild
5 (5.00%) high severe
Run Code Online (Sandbox Code Playgroud)
简短的回答是不,你不能。像这样的东西必须由regex板条箱本身提供。有一个开放问题跟踪它:https : //github.com/rust-lang/regex/issues/258
短期内不太可能支持这样的功能。一般来说,regex板条箱可以通过两种方式解决这个问题。第一种是使用 Serde 简单地序列化其内部数据结构。第二个是使内部实现与定制的序列化结构一致。
在第一种情况下,天真的方法的实现工作可能还不错,并且可能通过derive(serde::Serialize, serde::Deserialize)在几个地方洒一些来完成。这种方法有两个主要问题。首先,它需要一个显式的序列化步骤,该步骤会产生自己的成本,并且在足够多的情况下,它是否会比正则表达式编译本身更快,这一点尚不清楚。其次,这会将内部数据结构公开为公共 API 保证。所以实际上,实现这一点可能需要选择一种我们可以承诺的格式。这反过来可能需要在序列化之前和反序列化之后进行另一个翻译步骤,从而增加成本。所以总的来说,这种方法需要相当多的努力,目前尚不清楚它是否值得。
第二种方法将使序列化和反序列化有效地自由,因为内部表示将是序列化形式。这受到与第一个问题相同的“公共 API”格式保证的影响,因此必须小心完成以管理兼容性保证。这种方法的另一个主要问题是它会影响整个内部实现。实际上,所有内容的编写都必须考虑到这种约束。例如,不能再使用内部指针。因此,执行此操作所需的代码复杂性需要进行很大的权衡。而且工作量也很大。
其他人提到了对您的代码进行基准测试。你应该这样做,如果你能仔细证明为什么你需要消除编译成本,这个问题将是一个更好的问题。仅仅因为您正在编写一个高性能应用程序并且您在运行时使用使用模式字符串编译的正则表达式并不意味着正则表达式编译本身就是一个瓶颈。绝对有可能,但也很可能不是。因此,检查这个假设非常重要。理想情况下,您将创建一个最小的基准测试程序来重现您的应用程序的相同使用模式,然后测量您的程序的哪些方面使用了大部分时间。
说了这么多,该regex-automata箱子不支持(反)序列的正则表达式,它并因此使用我上面列出的第二种方法。但是,regex-automata它不是通用的正则表达式引擎,它与regexcrate之间存在严重差异。例如,使用regex-automata从用户输入派生的模式字符串编译正则表达式是不合适的,因为编译可能需要模式大小的指数时间。
| 归档时间: |
|
| 查看次数: |
132 次 |
| 最近记录: |