我对这里发生的事情有点困惑。我见过的大多数基准测试表明 Boost 在性能方面接近于 Perl,甚至超过它。然而,在我的脚本中,我的 Perl 实现速度快了 5-6 倍。
我在 test_script.cpp 和 test_script.pl 中打开文件并逐行读取,填充一个数组。然后,我针对线性定义中的正则表达式定义列表运行这些字符串,直到它们匹配,在这种情况下什么也没有发生(出于测试目的删除了 I/O),然后比较下一个字符串,等等,直到我们比较了所有字符串.
测试脚本.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.
}
测试脚本.cpp: 主要方法:
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);
填充数组方法:
static void populateArray(){
regexArray[1] = boost::regex ("\\/stuff\\/brands-([^\\/]*)\\/(.*)?");
regexArray[2] = boost::regex ("\\/coupons(\\/.*)?");
regexArray[3] = boost::regex ("\\/han\\/(.+)");
//continues on, 100 definitions.
}
获取规则方法:
static void getRule(string inQuery){
for(int i =1; i < 100; i++){
if(boost::regex_match(inQuery, regexArray[i])){
break;
}
}
我知道我在 perl 中做 if else 检查的线性列表可能看起来有点奇怪,但那是因为我必须稍后单独重新格式化每个规则。无论如何,除非我误解了什么,否则这两个脚本非常相似 - 它们查找这个正则表达式定义列表直到找到匹配项,然后它们继续处理其他传入的字符串。
那么为什么这些结果如此不同呢? 对于 100 条规则(两个脚本都使用相同的规则)和 10,000 个输入, .cpp 平均约为 0.155 秒,而 .pl 平均约为 0.028 秒。 编辑:使用编译器优化后,C++ 脚本的运行时间约为 0.091 秒,仍然较慢。
任何见解都值得赞赏。
最佳答案
除了打开编译器优化设置外,尝试使用 boost::regex_constants::optimize
选项,它会指示正则表达式库构建最佳正则表达式状态机。
static void populateArray(){
regexArray[1] = boost::regex ("\\/stuff\\/brands-([^\\/]*)\\/(.*)?", boost::regex_constants::optimize);
//continues on, 102 definitions.
}
此外,请务必通过对 getRule
的引用而不是通过值来传递,因为您不希望堆分配的潜在开销。
如果您可以确保编译器内联该函数,那最好。
此外,正如 Oals 在上面评论的那样,您没有像在 Perl 中那样使用 C++ 正则表达式中的开始和结束行 anchor 。 ^...$
关于c++ - Perl 正则表达式运行速度快于 C++ Boost 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38084354/