C++使用StringPiece减少string类的拷贝
C++使用StringPiece减少string类的拷贝
- 构造函数
- 操作
- 字符串比较
- Traits
- 参考链接
使用c++ string
类不可避免会带来很多不必要的拷贝,拷贝多了必然影响性能。因此在很多高性能C++框架的实现中,都会使用StringPiece类作为string类的wrapper,该类只持有目标字符串的指针,而避免额外的拷贝,比较常见的实现有:
- muduo实际上是使用了pcre的StringPiece的实现
- Chromium
Chromium也说明了引入StringPiece的意义,主要是为了免拷贝:
// You can use StringPiece as a function or method parameter. A StringPiece
// parameter can receive a double-quoted string literal argument, a "const
// char*" argument, a string argument, or a StringPiece argument with no data
// copying. Systematic use of StringPiece for arguments reduces data
// copies and strlen() calls.
pcre中也说明了StringPiece的使用注意事项
// ------------------------------------------------------------------
// Functions used to create STL containers that use StringPiece
// Remember that a StringPiece's lifetime had better be less than
// that of the underlying string or char*. If it is not, then you
// cannot safely store a StringPiece into an STL container
// ------------------------------------------------------------------
下面我们以muduo源码为例,讲解StringPiece的实现
构造函数
由于StringPiece不控制字符串的生命周期,因为调用方要保证在StringPiece的生命周期里,其指向的字符串始终有效
注意字符串的头指针ptr_
被定义为const
类型,其不允许任何修改
class StringPiece {private:const char *ptr_;int length_;public:// We provide non-explicit singleton constructors so users can pass// in a "const char*" or a "string" wherever a "StringPiece" is// expected.StringPiece() : ptr_(NULL), length_(0) {}StringPiece(const char *str): ptr_(str), length_(static_cast<int>(strlen(ptr_))) {}StringPiece(const unsigned char *str): ptr_(reinterpret_cast<const char *>(str)),length_(static_cast<int>(strlen(ptr_))) {}StringPiece(const std::string &str): ptr_(str.data()), length_(static_cast<int>(str.size())) {}StringPiece(const char *offset, int len) : ptr_(offset), length_(len) {}
...
};
操作
由于StringPiece不控制字符串的生命周期,因此字符串操作都是常数时间复杂度。
void clear() {ptr_ = NULL;length_ = 0;
}
void set(const char *buffer, int len) {ptr_ = buffer;length_ = len;
}
void set(const char *str) {ptr_ = str;length_ = static_cast<int>(strlen(str));
}
void set(const void *buffer, int len) {ptr_ = reinterpret_cast<const char *>(buffer);length_ = len;
}char operator[](int i) const { return ptr_[i]; }void remove_prefix(int n) {ptr_ += n;length_ -= n;
}void remove_suffix(int n) { length_ -= n; }
另外如果想使用StringPiece作为key使用hashmap,记得自定义哈希函数,这点可以查看Chromium的实现。
字符串比较
字符串的字典序比较,在==
和!=
这两种比较中,调用memcmp
比较到不相等的那一位为止
其他类型的比较中,按照短的长度进行比较,然后再根据需要的比较符号做判断
bool operator==(const StringPiece &x) const {return ((length_ == x.length_) && (memcmp(ptr_, x.ptr_, length_) == 0));
}
bool operator!=(const StringPiece &x) const { return !(*this == x); }#define STRINGPIECE_BINARY_PREDICATE(cmp, auxcmp) \
bool operator cmp(const StringPiece &x) const { \int r = memcmp(ptr_, x.ptr_, length_ < x.length_ ? length_ : x.length_); \return ((r auxcmp 0) || ((r == 0) && (length_ cmp x.length_))); \
}
STRINGPIECE_BINARY_PREDICATE(<, < );
STRINGPIECE_BINARY_PREDICATE(<=, < );
STRINGPIECE_BINARY_PREDICATE(>=, > );
STRINGPIECE_BINARY_PREDICATE(>, > );
#undef STRINGPIECE_BINARY_PREDICATE
Traits
由于StringPiece
只持有目标指针,所以是POD类型,并且拥有平凡构造函数,所以可以定义如下的type traits
以指示STL采用更为高效的算法实现。
#ifdef HAVE_TYPE_TRAITS
// This makes vector<StringPiece> really fast for some STL implementations
template <>
struct __type_traits<base::StringPiece> {typedef __true_type has_trivial_default_constructor;typedef __true_type has_trivial_copy_constructor;typedef __true_type has_trivial_assignment_operator;typedef __true_type has_trivial_destructor;typedef __true_type is_POD_type;
};
#endif
参考链接
- google StringPiece
- muduo::StringPiece
C++使用StringPiece减少string类的拷贝相关推荐
- C++---string类接口整理与深浅拷贝
string:是表示字符串序列的类,不能操作多字节或者变长字符序列 在使用string类时,必须包含#include头文件以及using namespace std; 常见的接口整理 常见的strin ...
- C++ String类写时拷贝 4
http://blog.51cto.com/zgw285763054/1839752 维基百科: 写入时复制(英语:Copy-on-write,简称COW)是一种计算机程序设计领域的优化策略.其核心思 ...
- string类的写时拷贝
由于浅拷贝使多个对象共用一块内存地址,调用析构函数时导致一块内存被多次释放,导致程序奔溃. 实现string类的时候通常显示的定义拷贝构造函数和运算符重载函数. 由于释放内存空间,开辟内存空间时花费时 ...
- string类的构造函数,拷贝构造函数,析构函数和赋值函数
String 类的原型如下 class String { public: String(const char *str=NULL); //构造函数 String(const String &o ...
- C++ string类(包括深浅拷贝)
目录 一.字符码表 一.为什么用string类 二.使用标准库中的string类 1.string类 2.string中的常用接口说明 (1)string类对象的常见构造 (2)string类对象访问 ...
- Java String类源码解析
String直接继承Object 含有一个char[] value,还有一个int hash默认值为0 new String()的构造产生的是一个值为""的字符数组 String( ...
- String类、StringBuffer类、StringBuilder类的区别
String是Java中基础且重要的类,并且String也是Immutable类的典型实现,被声明为final class,除了hash这个属性其它属性都声明为final,因为它的不可变性,所以例如拼 ...
- 内存分布malloc/calloc/realloc/free/new/delete、内存泄露、String模板、浅拷贝与深拷贝以及模拟string类的实现
内存分布 一.C语言中的动态内存管理方式:malloc/calloc/realloc和free 1.malloc: 从堆上获得指定字节的内存空间,函数声明:void *malloc (int n); ...
- C++【STL】【string类的使用】
目录 string类的常用接口说明 1. string类对象的常见构造 2. string类对象的容量操作 3. string类对象的访问及遍历操作 [LeetCode]反转字符串 string的迭代 ...
最新文章
- 码农技术炒股之路——抓取日线数据、计算均线和除权数据
- Windows Server 2008之三设置TCP/IP
- Zookeeper与paxos算法
- MVC是一种用于表示层设计的复合设计模式
- python上传文件到linux服务器_python上传大文件到服务器报错
- HTML5 获得canvas油漆环境
- Logistics模型预测银行贷款违约
- mysql 开发包 安装_mysql的zip包的安装方法
- 模式识别中常见概率符号公式的学习笔记 By Youki~
- Flash(as3.0) CScreen
- CH Round #72树洞[二分答案 DFSBFS]
- 一张纸厚度是多少毫米_一张纸对折后的厚度,有多可怕!——北京市第二十中学教科室“科技云课堂”(4)...
- php 中文日期转时间戳,php日期转时间戳,指定日期转换成时间戳
- python商城管理系统_【程序源代码】全端商城管理系统(后台+小程序)
- 经济学中的M0 M1 M2 M3的含义
- 《为何佛不显身制止战争?》
- matlab保存bln文件,气象万千(冯锦明课题组)-软件程序
- linux实训心得体会范文
- 深度学习笔记其五:卷积神经网络和PYTORCH
- 工程机械远程监控系统