为什么 `regex!` 不是 `Regex::new` 的包装器来提供相同的正则表达式匹配速度?

Why isn't `regex!` a wrapper for `Regex::new` to offer the same regex matching speed?

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

不幸的是,文档说:

WARNING: The regex! compiler plugin is orders of magnitude slower than the normal Regex::new(...) usage. You should not use the compiler plugin unless you have a very special reason for doing so.

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

答案很微妙:宏的一个特点是regex!的结果可以放入staticdata,像这样:

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

主要问题是 Regex::new() 在正则表达式编译期间使用堆分配。这是有问题的,需要重写 Regex::new() 引擎以允许静态存储。您还可以阅读 burntsushi's comment about this issue on reddit.


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

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

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

但是,编译器插件方法可以提供比 Regex::new() 更好的性能,后者已经非常快了:由于正则表达式的 DFA could be compiled into code instead of data,它有潜力 运行更快一点并受益于编译器优化。但未来必须做更多的研究才能确定。