C++ Perl正则表达式运行速度比C++;促进实施

C++ Perl正则表达式运行速度比C++;促进实施,c++,regex,perl,boost,C++,Regex,Perl,Boost,我对这里发生的事情有点困惑。我所看到的大多数基准测试的性能都接近Perl,甚至超过了Perl。然而,在我的脚本中,Perl实现的速度要快5-6倍 我在test_script.cpp和test_script.pl中打开文件并逐行读取,填充数组。然后,我针对线性定义中的正则表达式定义列表运行这些字符串,直到它们匹配为止,在这种情况下,不会发生任何事情(出于测试目的,删除了I/O),然后比较下一个字符串,等等,直到比较完所有字符串为止 Test_script.pl: #make incomingLis

我对这里发生的事情有点困惑。我所看到的大多数基准测试的性能都接近Perl,甚至超过了Perl。然而,在我的脚本中,Perl实现的速度要快5-6倍

我在test_script.cpp和test_script.pl中打开文件并逐行读取,填充数组。然后,我针对线性定义中的正则表达式定义列表运行这些字符串,直到它们匹配为止,在这种情况下,不会发生任何事情(出于测试目的,删除了I/O),然后比较下一个字符串,等等,直到比较完所有字符串为止

Test_script.pl:

#make incomingList, which contains all incoming strings
my $start = Time::HiRes::gettimeofday();

foreach (@incomingList) {
  my $inString = $_;
  &find_pattern($inString);
}

my $end = Time::HiRes::gettimeofday();
printf("%.6f\n", $end - $start);
查找模式方法:

sub find_pattern {
  my $URLString = $_[0];

  #1 rewrite
  if($URLString =~ m/^\/stuff\/brands-([^\/]*)\/(.*)?$/) {

  }
  #2 rewrite
  elsif($URLString =~ m/^\/coupons(\/.*)?$/){

  }
  #3 rewrite
  elsif($URLString =~ m/^\/han\/(.+)$/){

  }
  # ...continues on, there are 100 patterns. 
}
populateArray();
//make stringArr, which contains all incoming strings
struct timeval time;
gettimeofday(&time, NULL);
double t1=time.tv_sec+(time.tv_usec/1000000.0);   

for(int j =0; j < 10000; j++){
  getRule(stringArr[j]);
 }

gettimeofday(&time, NULL);
double t2=time.tv_sec+(time.tv_usec/1000000.0);
printf("%.6lf seconds elapsed\n", t2-t1);
Test_script.cpp: 主要方法:

sub find_pattern {
  my $URLString = $_[0];

  #1 rewrite
  if($URLString =~ m/^\/stuff\/brands-([^\/]*)\/(.*)?$/) {

  }
  #2 rewrite
  elsif($URLString =~ m/^\/coupons(\/.*)?$/){

  }
  #3 rewrite
  elsif($URLString =~ m/^\/han\/(.+)$/){

  }
  # ...continues on, there are 100 patterns. 
}
populateArray();
//make stringArr, which contains all incoming strings
struct timeval time;
gettimeofday(&time, NULL);
double t1=time.tv_sec+(time.tv_usec/1000000.0);   

for(int j =0; j < 10000; j++){
  getRule(stringArr[j]);
 }

gettimeofday(&time, NULL);
double t2=time.tv_sec+(time.tv_usec/1000000.0);
printf("%.6lf seconds elapsed\n", t2-t1);
getRule方法:

static void getRule(string inQuery){
  for(int i =1; i < 100; i++){
    if(boost::regex_match(inQuery, regexArray[i])){
      break; 
     }
  }
静态void getRule(查询中的字符串){
对于(int i=1;i<100;i++){
if(boost::regex_匹配(inQuery,regexArray[i])){
打破
}
}
我知道在perl中执行if-else检查的线性列表可能有点奇怪,但那是因为我以后必须独立地重新格式化每个规则。不管怎样,除非我误解了什么,否则这两个脚本非常相似——它们查找正则表达式定义列表,直到找到匹配项,然后共同使用继续使用其他传入字符串

那么,为什么这些结果如此不同呢? 对于100条规则(两个脚本使用相同的规则)和10000条输入, .cpp的平均值约为0.155秒,.pl的平均值约为0.028秒。 编辑:在编译器优化的地方,C++脚本在大约0.091秒的时间内运行,速度仍然较慢。
任何洞察都将不胜感激。

除了打开编译器优化设置外,还可以尝试使用
boost::regex_constants::optimize
选项,该选项将指导regex库构建最优化的regex状态机

static void populateArray(){
regexArray[1] =  boost::regex ("\\/stuff\\/brands-([^\\/]*)\\/(.*)?", boost::regex_constants::optimize);
//continues on, 102 definitions. 
}
另外,请确保通过引用传递到
getRule
,而不是通过值传递,因为您不希望堆分配的潜在开销

如果您能确保编译器内联函数,那就最好了


同样,上面提到的OALS,你没有使用C++的正则表达式中的开始和结束行锚,就像Perl中的。^…$/p>你用优化编译了吗?你在调试中运行吗?注意Perl版本中的第二个模式不是锚定在末端的。另外,我不使用Boost,但是如果我记得DeFa的话。ult模式使用ECMA正则表达式引擎,您是否尝试使用PCRE正则表达式引擎(具有更多优化功能)@ Yayahii需要建立优化的C++应用程序,意思是“代码> -O2, -O3等等。如果你正在对一个未优化的构建进行计时,那么你看到的结果毫无意义。此外,给我们一个优化的构建结果确保我们在没有问题的时候不浪费时间去解决一个问题。@Yayahii

-o
选项不是用于优化的。它是一个对象文件指令。现在,您正在使用默认的
-O0
进行编译,这不是优化,因此您关于性能的问题仍然是不确定的,尽管您向我们展示了计时以及您声称Perl比Boost快。请请指定我提到的选项之一(
-O2
-O3
,等等)。我对Boost一无所知,但您的Perl正则表达式是从
^
开始的,而Boost正则表达式则不是。这可能是它的一部分,尽管我不确定它是否能单独解释所有这些差异?谢谢,我会研究它。