浅谈正则表达式——C++正则替换引起的性能下降-创新互联

目录
  • 问题引入
  • 正则替换测试
  • 常规方法测试
  • 模拟外部多次调用
  • 正则性能差的原因
  • 写在最后

网站设计制作、网站设计的关注点不是能为您做些什么网站,而是怎么做网站,有没有做好网站,给创新互联一个展示的机会来证明自己,这并不会花费您太多时间,或许会给您带来新的灵感和惊喜。面向用户友好,注重用户体验,一切以用户为中心。问题引入

最近在一次解析大文件(10万+行)时,处理空格用到了正则替换,却没想到带来了性能上的问题,特别在此记录给需要的人避坑。假如要用C++处理一个字符串首尾的空格,可以用正则,可以用string自带的erase方法,下面是对这两种方法性能上的测试:

正则替换测试
#include#include#includeusing namespace std;

void trimmed(std::string& str) {str = regex_replace(str, std::regex("^\\s+"), "");
    str = regex_replace(str, std::regex("\\s+$"), "");
}

int main() {string str1 = "   123 45 tr54 ewre  "; //字符串首尾共5个空格
	cout<< "str1.length = "<< str1.length()<< endl;
	auto t1 = std::chrono::steady_clock::now();
	trimmed(str1);
	auto t2 = std::chrono::steady_clock::now();
	double elapse = std::chrono::duration(t2-t1).count();
	cout<< "regex replace use "<< elapse<< "ms"<< endl;
	cout<< "str1.length = "<< str1.length()<< endl;
	cout<< str1<< endl;
	return 0;
}

测试结果如下:
在这里插入图片描述
使用正则替换,执行完成一次大概耗时0.4ms,看起来耗时很短,但如果乘以100000呢?
0.4ms * 100000 = 40000ms = 40s

常规方法测试

接下来使用string自带的erase方法测试

#include#include#includeusing namespace std;

void Trimmed(std::string& str) {str = str.erase(0, str.find_first_not_of(" "));
    str = str.erase(str.find_last_not_of(" ") + 1);
}

int main() {string str2 = "   123 45 tr54 ewre  "; //字符串首尾同样是5个空格
    cout<< "str2.length = "<< str2.length()<< endl;
    auto t3 = std::chrono::steady_clock::now();
    Trimmed(str2);
    auto t4 = std::chrono::steady_clock::now();
    double elapse = std::chrono::duration(t4-t3).count();
    cout<< "erase use "<< elapse<< "ms"<< endl;
    cout<< "str2.length = "<< str2.length()<< endl;
    cout<< str2<< endl;
    return 0;
}

测试结果如下
在这里插入图片描述
使用erase去除空格,执行一次大概耗时0.0008ms,而正则替换耗时几乎是它的500倍(0.4ms),这个差距就很大了。即使乘以100000,erase耗时0.0008ms * 100000 = 80ms,erase给人的感觉是极致丝滑,正则替换则是程序半天无响应。而这个差距在多次外部调用的情况下更加明显,看下面的模拟测试:

模拟外部多次调用
void test01() {auto t1 = std::chrono::steady_clock::now();
    for (int i = 0; i< 100000; i++) {string str = "   123 45 tr54 ewre  ";
        trimmed(str);
    }
    auto t2 = std::chrono::steady_clock::now();
    double elapse = std::chrono::duration(t2-t1).count();
    cout<< "regex----->"<< elapse<< "ms"<< endl;
}

void test02() {auto t1 = std::chrono::steady_clock::now();
    for (int i = 0; i< 100000; i++) {string str = "   123 45 tr54 ewre  ";
        Trimmed(str);
    }
    auto t2 = std::chrono::steady_clock::now();
    double elapse = std::chrono::duration(t2-t1).count();
    cout<< "erase=====>"<< elapse<< "ms"<< endl;
}

test01和test02分别模拟使用正则替换和erase处理10万行的文本中的首尾空格,结果如下:
在这里插入图片描述
现在这个差距已经不是500倍了,而是夸张的2300多倍!!!这在性能上是完全不可接受的,故而正则替换性能较差,不建议使用正则去空格。
在这里插入图片描述

正则性能差的原因

主要是正则表达式的引擎会导致字符匹配时会发生回溯,此处不做过多叙述,感兴趣的小伙伴可以去阅读正则表达式引起的性能下降一文,一定会有所收获的。

写在最后

不用不知道,正则虽然处理文本很强,但用错了地方,可能带来负面效果,coding就是从这个坑出来,掉进另一个坑里,这其中的乐趣,大概就是爬上坑的过程吧哈哈。

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


网页题目:浅谈正则表达式——C++正则替换引起的性能下降-创新互联
网址分享:http://scyanting.com/article/isoss.html