昨天对长目标字符串下的各种正则匹配库性能进行了总结,得出结论是Boost regex性能最佳。今天将其应用到项目当中,果不其然,长字符串匹配带来的性能损失基本没有了,当然,目前规模并不算太大,但是在可预计规模内Boost可以完全达到要求。
不过有一点,在Boost,C同时去除长字符串匹配的影响后,剩下都是短字符串匹配,发现Boost比C好的并不是好很多,例如10000+次短字符匹配中,其中包含匹配成功和不成功的,Boost regex+系统其他模块用时130ms左右,而C regex+系统其他模块140ms左右,二者相差甚小。
当然,这个时候我在项目中用Boost regex是对模式字符串重复编译的,没有预编译。
经过下文的探究,你会发现,昨天文中提到长字符串下C regex模式字符串预编译和不预编译对性能差别影响较小,但是在短字符串下就不能忽视了,对Boost的Regex影响更是甚大。
首先,我们将昨天的测试字符串换成短字符串,然后在Boost regex下测试不预编译和预编译模式字符串的性能差异。
测试代码如下,通过宏定义#define PRE_COMP ( 0 )表示不预编译,#define PRE_COMP ( 1 )表示预编译,两种模式各循环匹配10000次。
/* * Program: * This program test boost regex performance for short target string * Platform * Ubuntu14.04 g++-4.8.2 * History: * weizheng 2014.11.07 1.0 */ #include <boost/regex.hpp> #include <sys/time.h> #include <cstdio> /* * choice whether to pre-complie the pattern string, 1 or 0 */ #define PRE_COMP ( 1 ) const int LOOP_COUNT = 10000; /************************************ main ************************************/ int main() { #if PRE_COMP boost::regex pattern("commonquery.jsp.*keyName=YwdjywcQueryMain&queryAction=cxywcdj"); std::string target ="/YGFMISWeb/faces/query/commonquery/commonquery.jsp?^query/keyName=YwdjywcQueryMain&queryAction=cxywcdj"; #endif /* * record the start time */ struct timeval tv_start, tv_end; gettimeofday(&tv_start, NULL); int count = 0; for(int i = 0; i < LOOP_COUNT; i++) { #if !PRE_COMP boost::regex pattern("commonquery.jsp.*keyName=YwdjywcQueryMain&queryAction=cxywcdj"); std::string target ="/YGFMISWeb/faces/query/commonquery/commonquery.jsp?^query/keyName=YwdjywcQueryMain&queryAction=cxywcdj"; #endif if(boost::regex_search(target, pattern)) { count++; } } /* * record the end time */ gettimeofday(&tv_end, NULL); unsigned long time_used = (tv_end.tv_sec * 1000000 + tv_end.tv_usec - (tv_start.tv_sec * 1000000 + tv_start.tv_usec))/1000; printf("used: %lu ms\n", time_used); printf("matched %d times\n", count); return 0; }结果如下,不预编译模式字符串平均情况如下:
weizheng@weizheng-MS-7798:~/test$ ./boost_regex_main used: 38 ms matched 10000 times而预编译的情况会好不少:
weizheng@weizheng-MS-7798:~/test$ ./boost_regex_main used: 11 ms matched 10000 times所以,对于Boost regex来说,一定要使用预编译字符串的模式,不要等到匹配时才编译模式字符串。
/* * Program: * This program test c regex performance for short target string * Platform * Ubuntu14.04 gcc-4.8.2 * History: * weizheng 2014.11.07 1.0 */ #include <sys/time.h> #include <stdio.h> #include "regex.h" /* * choice whether to pre-complie the pattern string, 1 or 0 */ #define PRE_COMP ( 0 ) #define LOOP_COUNT ( 10000 ) /************************************ main ************************************/ int main(void) { char pattern[]="commonquery.jsp.*keyName=YwdjywcQueryMain&queryAction=cxywcdj"; char target[]="/YGFMISWeb/faces/query/commonquery/commonquery.jsp?^query/keyName=YwdjywcQueryMain&queryAction=cxywcdj"; #if PRE_COMP regex_t oRegex; if (regcomp(&oRegex, pattern, 0)) printf("regex complie error\n"); #endif /* * record the start time */ struct timeval tv_start, tv_end; gettimeofday(&tv_start, NULL); /* * matching */ int count = 0; for(int i = 0; i < LOOP_COUNT; i++) { #if PRE_COMP if(match_pre_comp(&oRegex, target)) #endif #if !PRE_COMP if(match(pattern, target)) #endif { count++; } } /* * record the end time */ gettimeofday(&tv_end, NULL); unsigned long time_used = (tv_end.tv_sec * 1000000 + tv_end.tv_usec - (tv_start.tv_sec * 1000000 + tv_start.tv_usec))/1000; #if PRE_COMP regfree(&oRegex); #endif printf("used: %lu ms\n", time_used); printf("matched %d times\n", count); return 0; }结果如下,不预编译模式字符串平均情况如下:
weizheng@weizheng-MS-7798:~/test$ ./c_regex_main used: 52 ms matched 10000 times预编译的情况:
weizheng@weizheng-MS-7798:~/test$ ./c_regex_main used: 42 ms matched 10000 times其实比起长字符串下的两种模式,这也是相差也不算小,主要看百分比,如果规模变大,不预编译10000ms,那么预编译就是8000ms。
关于Boost,C Regex对短目标字符串正则匹配的性能分析
原文地址:http://blog.csdn.net/we_izheng/article/details/40891705