14

Rust Regex crate提供了语法扩展,regex!可以在标准编译时间内编译正则表达式。这有两个好处:

  • 我们不需要在运行时做这项工作(更好的程序性能)
  • 如果我们的正则表达式格式错误,编译器可以在编译期间告诉我们,而不是触发运行时恐慌

不幸的是,文档说:

警告:编译regex!器插件比正常Regex::new(...)使用慢几个数量级。除非您有非常特殊的原因,否则不应使用编译器插件。

这听起来像是用于regex!与 for完全不同的正则表达式引擎Regex::new()。为什么不regex!()只是一个包装器Regex::new()来结合两个世界的优势?据我了解,这些语法扩展编译器插件可以执行任意代码;为什么不Regex::new()呢?

4

1 回答 1

13

答案很微妙:宏的一个特点是可以将结果regex!放入静态数据中,如下所示:

static r: Regex = regex!("t?rust");

主要问题是Regex::new()在正则表达式编译期间使用堆分配。这是有问题的,并且需要重写Regex::new()引擎以允许静态存储。您还可以在 reddit 上阅读 burntsushi 关于此问题的评论


有一些关于如何改进的建议regex!

  • 放弃static支持并在编译时验证正则表达式字符串,同时仍在运行时编译正则表达式
  • static通过使用类似的技巧来lazy_static!保持支持

截至 2017 年初,开发人员专注于稳定标准 API 以发布 1.0 版本。因为regex!无论如何都需要一个夜间编译器,所以它现在的优先级很低。

但是,compiler-plugin 方法可以提供比Regex::new()已经超快的更好的性能:由于正则表达式的 DFA 可以编译为 code 而不是 data,它有可能运行得更快一些,并从编译器优化中受益。但未来还需要做更多的研究才能确定。

于 2017-01-06T10:40:10.833 回答