【问题标题】:Why does a continuous initialization of a std::regex object slow down the program?为什么 std::regex 对象的连续初始化会减慢程序的速度?
【发布时间】:2016-05-07 16:58:18
【问题描述】:

我有以下代码 sn-p 从std::cin 读取行并将它们打印到std::cout

#include <iostream>
#include <string>
#include <regex>
int main() {

  //std::regex e2("([^[:blank:]]+)|(\"[^\"]+\")|(\\([^\\)]+\\))");
  const size_t BUFSIZE = (1<<10);
  std::string buffer;
  buffer.reserve( BUFSIZE );

  while (std::getline( std::cin, buffer )) {
    std::cout << buffer << std::endl;
    //std::regex e1("([^[:blank:]]+)|(\"[^\"]+\")|(\\([^\\)]+\\))");
  }
  return 0;
}

对于 9800 行的输入,执行时间非常快:

real    0m0.116s
user    0m0.056s
sys     0m0.024s

但是,如果我在 while 循环中取消注释 std::regex e1 对象,执行时间会大大减慢:

real    0m2.859s
user    0m2.800s
sys     0m0.032s

另一方面,在循环外取消注释std::regex e2 对象,执行时间完全不受影响。考虑到我没有应用任何正则表达式匹配,但我只是在构造一个对象,为什么会发生这种情况?

注意:我已经看到 this 线程但没有发现任何问题。

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    为了使匹配快速,必须将模式处理成允许快速匹配的形式,这需要大量时间。这通常在构造正则表达式对象期间完成;事实上,这就是构造正则表达式对象的全部意义所在!如果在构建过程中没有做额外的工作,那么拥有一个单独的正则表达式对象就没有任何意义——匹配函数只会将模式作为原始字符串接收并使用它。

    【讨论】:

      【解决方案2】:

      正则表达式匹配主要实现为finite state machine。实现需要构建这个状态机。状态机取决于您提供的正则表达式。一些正则表达式通常具有非常复杂的有限状态机。复杂性将是正则表达式中可能的分支数量的一个因素。状态机越复杂,设置正则表达式对象所需的工作就越多,它才能开始匹配输入字符串。

      正如@Mehrdad 正确指出的那样,正则表达式接口存在而不是辅助函数的唯一原因是分离设置状态机的繁重操作,然后每个搜索操作将相对较轻。

      Here 是 std::regex 的提案,详细讨论了这些设计 NIT

      【讨论】:

      • 理论与实践的有趣融合。 :)
      猜你喜欢
      • 1970-01-01
      • 2016-09-28
      • 2018-03-11
      • 2020-05-11
      • 1970-01-01
      • 2021-05-19
      • 1970-01-01
      • 2019-05-29
      • 2018-11-30
      相关资源
      最近更新 更多