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

时间:2017-01-06 10:40:11

标签: rust rust-compiler-plugin

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

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

不幸的是,文档说:

  

警告: regex!编译器插件比正常Regex::new(...)使用速度慢几个数量级。您不应该使用编译器插件,除非您有非常特殊的理由这样做。

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

1 个答案:

答案 0 :(得分:8)

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

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

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

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

  • 删除static支持并在编译时验证正则表达式字符串,同时在运行时编译正则表达式
  • 使用与static相似的技巧
  • 保持lazy_static!支持

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

然而,编译器插件方法可以提供比Regex::new()更好的性能,[self.btnDelete addTarget:self action:@selector(btnTocuhDown:) forControlEvents:UIControlEventTouchDown]; [self.btnDelete addTarget:self action:@selector(btnTouchUp:) forControlEvents:UIControlEventTouchUpInside]; [self.btnDelete addTarget:self action:@selector(btnTouchUp:) forControlEvents:UIControlEventTouchUpOutside]; 已经超级快:因为正则表达式的DFA could be compiled into code instead of data,它有可能运行得更快并从中受益编译器优化。但是,未来还需要做更多的研究才能确定。