C linux正则表达式性能问题

C linux正则表达式性能问题,c,regex,linux,cpu-usage,C,Regex,Linux,Cpu Usage,我正在创建一个程序,逐行读取文件,将该行与正则表达式匹配,并显示有多少行与该正则表达式匹配。问题是,这个程序使用了相当大的CPU资源67.5%不带valgrind和带valgrind100.1%并且84000行的速度非常慢~5秒。valgrind输出如下(输入文件为84000行) 为什么要用这么多cpu?为什么要花这么长时间?。有没有办法让它更快,使用更少的内存,cpu?多谢各位 ==10737== HEAP SUMMARY: ==10737== in use at exit: 0 by

我正在创建一个程序,逐行读取文件,将该行与正则表达式匹配,并显示有多少行与该正则表达式匹配。问题是,这个程序使用了相当大的CPU资源
67.5%
不带valgrind和带valgrind
100.1%
并且84000行的速度非常慢
~5秒
。valgrind输出如下(输入文件为84000行)

为什么要用这么多cpu?为什么要花这么长时间?。有没有办法让它更快,使用更少的内存,cpu?多谢各位

==10737== HEAP SUMMARY:
==10737==     in use at exit: 0 bytes in 0 blocks
==10737==   total heap usage: 42,200,387 allocs, 42,200,387 frees, 5,441,088,516 bytes allocated
==10737== 
==10737== All heap blocks were freed -- no leaks are possible
==10737== 
==10737== For counts of detected and suppressed errors, rerun with: -v
==10737== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)
源代码:

#include <stdio.h>
#include "stdlib.h"
#include <string.h>
#include <regex.h>

int check_regex(char* line);
void regex_test(const char* log_file);

int main(){
    regex_test("/var/log/syslog");
}

void regex_test(const char* log_file){
    printf("%s\n", log_file);
   FILE * fp;
   char * line = NULL;
   size_t len = 0;
   ssize_t read;
   int line_count=0;
   int match_count=0;
   fp = fopen(log_file, "r");
   if (fp == NULL)
       exit(EXIT_FAILURE);

   while ((read = getline(&line, &len, fp)) != -1) {
    // printf("%p\n", &line);
    if (check_regex(line))
    {
      match_count++;
    }else{
      printf("%s", line);
      printf("%d\n", line_count);
      // exit(0);
    }
    line_count++;
   }
   printf("%d/%d\n",match_count, line_count);
   fclose(fp);
   if (line)
       free(line);
}

int check_regex(char* line){
  regex_t regex;
  if (regcomp(&regex,"^(\\w+[ ]+[0-9]+ [0-9]+:[0-9]+:[0-9]+) [A-Za-z0-9-]+ [A-Za-z\\/]+\\[?[^]:]*\\]?: <?(\\w+)?>? ?(.+)$", REG_EXTENDED)) {
      printf("Could not compile regex\n");
      exit(1);
  }
  if (!regexec(&regex, line, 0, NULL, 0)) {
      // printf("Match\n");
      regfree(&regex);
      return 1;
  }
  else{
      // printf("No Match\n");
      regfree(&regex);
      return 0;
  }
}
#包括
#包括“stdlib.h”
#包括
#包括
int check_regex(字符*行);
无效正则表达式测试(常量字符*日志文件);
int main(){
regex_测试(“/var/log/syslog”);
}
无效正则表达式测试(常量字符*日志文件){
printf(“%s\n”,日志文件);
文件*fp;
char*line=NULL;
尺寸长度=0;
阅读;
int line_count=0;
int match_count=0;
fp=fopen(日志文件,“r”);
如果(fp==NULL)
退出(退出失败);
while((read=getline(&line,&len,fp))!=-1){
//printf(“%p\n”,&line);
如果(勾选正则表达式(行))
{
匹配_计数++;
}否则{
printf(“%s”,第行);
printf(“%d\n”,行计数);
//出口(0);
}
行数++;
}
printf(“%d/%d\n”,匹配计数,行计数);
fclose(fp);
如果(行)
自由线;
}
int check_regex(字符*行){
regex_t regex;
如果(regcomp(®ex,“^(\\w++[+[0-9]+[0-9]+:[0-9]+:[0-9]+:[0-9]+:[0-9]+[A-Za-z0-9-]+[A-Za-z\\/]+\[?[^]:]*\\]:(.+)$”,regu扩展)){
printf(“无法编译regex\n”);
出口(1);
}
if(!regexec(®ex,line,0,NULL,0)){
//printf(“匹配\n”);
regfree(®ex);
返回1;
}
否则{
//printf(“不匹配\n”);
regfree(®ex);
返回0;
}
}

首先,如果某个设备的cpu使用率低于100%,则意味着瓶颈是I/O或其他设备,而不是cpu


话虽如此。每次调用
check\u regex
函数时,都要重新编译正则表达式。这似乎效率很低。正则表达式匹配以这种方式拆分的原因是正则表达式的编译可能非常慢。您应该编译一次正则表达式,然后根据需要多次重用它。

您应该只创建一次正则表达式对象,现在,每次发送一行进行检查时都会重新创建它。将
regcomp
移动到
check_regex
之外,我认为您将有更好的性能。是的,正如@stribizev所说。在C中看到这一点是不寻常的,通常是C++的DVS,他们坚持不断地创建和破坏复杂的结构/对象/子系统: