C++ Perl正则表达式运行速度比C++;促进实施
我对这里发生的事情有点困惑。我所看到的大多数基准测试的性能都接近Perl,甚至超过了Perl。然而,在我的脚本中,Perl实现的速度要快5-6倍 我在test_script.cpp和test_script.pl中打开文件并逐行读取,填充数组。然后,我针对线性定义中的正则表达式定义列表运行这些字符串,直到它们匹配为止,在这种情况下,不会发生任何事情(出于测试目的,删除了I/O),然后比较下一个字符串,等等,直到比较完所有字符串为止 Test_script.pl: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
#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,
-o
选项不是用于优化的。它是一个对象文件指令。现在,您正在使用默认的-O0
进行编译,这不是优化,因此您关于性能的问题仍然是不确定的,尽管您向我们展示了计时以及您声称Perl比Boost快。请请指定我提到的选项之一(-O2
,-O3
,等等)。我对Boost一无所知,但您的Perl正则表达式是从^
开始的,而Boost正则表达式则不是。这可能是它的一部分,尽管我不确定它是否能单独解释所有这些差异?谢谢,我会研究它。