使用 std::string_view 提升字符串处理性能
C++标准库提供了一个非常优秀的字符串处理类std::string,我们可以通过该类完成各种字符串操作。但是std::string有一个缺点,它的很多操作都是针对字符串实体,存在不必要的内存拷贝的代码,导致字符串的处理性能不尽如人意。
针对这种情况C++17标准引入了std::string_view这个类,该类不会直接作用在字符串实体上,而是记录字符串处理的位置,这样就可以保证用最小的代价对字符串进行处理。
在几个月前写过 std::string_view 的一些简洁介绍,在其中有提及:Here
做函数形参的时候,使用
std::string_view基本一定优于老式的const std::string&这种写法。
为了验证这个结论,下面的代码实现了一个断词器,然后针对 \(64MB\) 的数据做断词处理并且分别记录使用std::string和std::string_view作为基础类型时断词器运行的时间:
#include <iostream>
#include <chrono>
#include <string_view>
template<class T>
struct tokenizer {
using string_type = T;
using value_type = typename T::value_type;
tokenizer(const string_type & str,
std::enable_if_t<std::disjunction_v<
std::is_same<string_type, std::basic_string<value_type>>,
std::is_same<string_type, std::basic_string_view<value_type>>>> * = nullptr)
: data_(str), begin_(0), end_(0) {}
string_type operator()(const value_type sep) {
for ( ; end_ < data_.size(); ++end_ )
{
if (data_[end_] == sep)
{
auto res = data_.substr(begin_, end_ - begin_);
begin_ = ++end_;
return res;
}
}
if (end_ <= data_.size())
{
return data_.substr(begin_, end_);
}
return "";
}
bool more() const { return end_ < data_.size(); }
private:
const string_type data_;
size_t begin_, end_;
};
auto make_string_data(size_t count, char sep) {
std::string data;
for ( size_t i = 0; i < count; ++i )
{
data.push_back('a' + i % 26);
if (i + 1 != count)
data.push_back(sep);
}
return data;
}
int main() {
auto data = make_string_data(1024 * 1024 * 32, ' ');
{
tokenizer<std::string> tk(data);
auto start = std::chrono::high_resolution_clock::now();
while ( tk.more())
{
tk(' ');
}
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> diff = end - start;
std::cout << "elapsed time = " << diff.count() << std::endl;
}
{
tokenizer<std::string_view> tk(data);
auto start = std::chrono::high_resolution_clock::now();
while ( tk.more())
{
tk(' ');
}
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> diff = end - start;
std::cout << "elapsed time = " << diff.count() << std::endl;
}
return 0;
}
在上面的代码中tokenizer是一个断词器的类模板,接受std::string、std::wstring等std::basic_string模板实例化的类型,同时也能接受std::string_view、std::wstring_view等std::basic_string_view模板实例化的类型。这里采用了SFINAE的方法来约束tokenizer的模板实参必须为以上类型。如果编译环境是C++20标准,可以采用概念来约束模板实参类型。
这份代码tokenizer<std::string>运行结果是0.45秒,如果将tokenizer<std::string>替换为tokenizer<std::string_view>运行时间缩短为0.08秒,性能提升是非常明显的 。

使用 std::string_view 提升字符串处理性能的更多相关文章
- .NET Core中妙用unsafe减少gc提升字符串处理性能
一.前言 昨天在群里讨论怎么样效率的把一个字符串进行反转,一般的情况我们都知道,只要对String对象进行操作,那么就会生成新的String对象,比如"1"+"2&quo ...
- C# 利用StringBuilder提升字符串拼接性能
一个项目中有数据图表呈现,数据量稍大时显得很慢. 用Stopwatch分段监控了一下,发现耗时最多的函数是SaveToExcel 此函数中遍列所有数据行,通过Replace替换标签生成Excel行,然 ...
- dotnet 6 使用 string.Create 提升字符串创建和拼接性能
本文告诉大家,在 dotnet 6 或更高版本的 dotnet 里,如何使用 string.Create 提升字符串创建和拼接的性能,减少拼接字符串时,需要额外申请的内存,从而减少内存回收压力 本文也 ...
- jQuery 做好七件事帮你提升jQuery的性能
1. Append Outside of Loops 凡是触及到DOM都是有代价的.如果你向DOM当中附加大量的元素,你会想一次性将它们全部附加进来,而不是分多次进行.当在循环当中附加元素就会产生一个 ...
- java字符串格式化性能对比String.format/StringBuilder/+拼接
String.format由于每次都有生成一个Formatter对象,因此速度会比较慢,在大数据量需要格式化处理的时候,避免使用String.format进行格式化,相反使用StringUtils.l ...
- Jmeter 压力测试笔记(3)--脚本调试/签名/cookie/提升吞吐量/降低异常率/提升单机并发性能
import XXXsign.Openapi2sign;---导入jar包中的签名方法 String str1 = "12121"; ---需要被签名的字段:向开发了解需要哪些哪些 ...
- 提升VMware虚拟机性能招数
在VMware虚拟机(VMware Workstation或VMware Server)中我们可以同时运行多个Guest OS,当同时在同一Host OS中运行多台虚拟机时势必会严重影响到Host O ...
- psutil 是因为该包能提升 memory_profiler 的性能
python 性能分析入门指南 一点号数据玩家昨天 限时干货下载:添加微信公众号"数据玩家「fbigdata」" 回复[7]免费获取[完整数据分析资料!(包括SPSS.SAS.SQ ...
- 如何提升 CSS 选择器性能
CSS 选择器性能损耗来自? CSS选择器对性能的影响源于浏览器匹配选择器和文档元素时所消耗的时间,所以优化选择器的原则是应尽量避免使用消耗更多匹配时间的选择器.而在这之前我们需要了解CSS选择器匹配 ...
- 七个可以提升python程序性能的好习惯,你知道吗?
掌握一些技巧,可尽量提高Python程序性能,也可以避免不必要的资源浪费.今天就为大家带来七个可以提升python程序性能的好习惯,赶快来学习吧:. 1.使用局部变量 尽量使用局部变量代替全局变量:便 ...
随机推荐
- 【Android】学习day05|简单登陆页面的实现|监听代码
实现效果如下图所示 实现代码[部分] MainActivity.java 1 package com.example.app02; 2 3 import androidx.appcompat.app. ...
- RTMP协议学习——Message与Chunk解读
前言 之前通过对抓包数据的学习和分析,对RTMP协议有了一个整体的认知,大致了解了RTMP从建立连接到播放视频的流程,文章请看<RTMP协议学习--从握手到播放>.但是对于RTMP消息传输 ...
- [CF1034C] Region Separation
题目描述 There are $ n $ cities in the Kingdom of Autumn, numbered from $ 1 $ to $ n $ . People can trav ...
- MybatisPlus最新代码生成器(version3.5.1+),自定义文件模板
1.导入依赖(我这里用的是gradle构建工具,maven也一样啦~) plugins { id 'java' id 'org.springframework.boot' version '2.7.3 ...
- 换热站数字孪生 | 图扑智慧供热 3D 可视化
前言 换热站作为供热系统不可或缺的一部分,其能源消耗对城市环保至关重要.在双碳目标下,供热企业可通过搭建智慧供热系统,实现供热方式的低碳.高效.智能化,从而减少碳排放和能源浪费.通过应用物联网.大数据 ...
- 基于一维卷积神经网络模型的AI量化智能选股策略
这是早前BigQuant专题研究:基于卷积神经网络CNN的深度学习因子选股模型.卷积神经网络(Convolutional Neural Network, CNN),是计算机视觉研究和应用领域中最具影响 ...
- DHorse v1.5.0 发布,基于 k8s 的发布平台
版本说明 新增特性 支持同一机器部署多个DHorse服务: 支持Next..NET应用部署: 优化Node.Nuxt应用构建和部署的性能: 默认使用fabric8客户端与k8s集群交互,可以通过指定参 ...
- 华企盾DSC手机app登录不上常见处理方法
1.DSC服务器是否正常运行. 2.telnet外网是否通.(需要在程序与功能中添加telnet功能才能在cmd窗口用telnet命令 举例:telnet 172.17.2.20 5558) 3.其它 ...
- Java反序列化漏洞-CC6链分析
CC6利用链分析 经过之前对CC1链和URLDNS链的分析,现在已经对反序列化利用链有了初步的认识,这次来分析一个最好用的CC利用链--CC6. 为什么CC6是最好用的CC利用链,因为CC6不限制jd ...
- JavaScript 常见错误与异常处理
一.为什么要了解常见JS错误 1.调试和故障排除: 了解常见的JavaScript错误可以帮助你更好地调试和故障排除代码.当你遇到错误时,能够快速识别错误类型并找到解决方法,可以节省大量的时间和精力. ...