学习 LLVM(4) StringRef 类

类 StringRef 定义在文件 llvm/include/ADT/StringRef.h 中html

== 说明 ==
StringRef 数据类表示一个固定不变的字符串的引用(包括一个字符数组的指针和长度),它支持可用在 std::string 类上的各类通用字符串操做,可是不须要进行内存的分配。所引用的字符串不须要以 null 字符结尾。数组

StringRef 本身不拥有字符串数据,在使用 StringRef 的时候指望字符串放在别的地方,而存放的地方的声明周期要超过 StringRef 的。所以,通常保存 StringRef 本身是不安全的。安全

StringRef 能够引用一个外部实际字符串的一部分,例如 const char *s = "abcdefg",
StringRef(s+1, 4) 表示引用从s+1 位置开始的长度为 4 的子字符串,也即 "bcde"。函数

参见:http://llvm.org/docs/ProgrammersManual.html#StringRef性能

== 实现 ==
StringRef 的实现简化以下:设计

class StringRef {
  const char *Data;  // 字符串的开始位置,指向一个外部的缓冲区(不属于 StringRef 管理)
  size_t Length;   // 字符串的长度。

  StringRef(...)   // 多种形态的构造函数
  
  data(), size()   // 得到 Data, Length 的 inline 函数。
  begin(), end(), empty(), size(), front(), back(), [] 等相似于 STL 容器标准方法的函数。
  equals(), compare(), startswith(), find(), substr(), split() 等通常字符串操做
  std::string, str()  // 转换为标准 std::string
  // 其它略
}
多个 StringRef 二元操做符 operator <, >, ==, !=, >=, <=, += 的重载。
模板 isPodLike<StringRef> 的特化,可将 StringRef 做为 POD 数据对待。

 

* StringRef 实例比较小(sizeof 值为 8),它足够小于是能够直接做为参数传递,或做为返回值类型。指针

== 为什么要设计 StringRef 类等问题 ==
* 我认为是 LLVM 在设计和实现上高度追求性能,在类的设计使用上力求精确、高效。在一些场合,字符串已知有拥有者,须要传递其所有或部分字符串到别的函数,此时,使用 StringRef 能够减小字符串分配、分割、裁剪等各类操做带来的空间需求。
* StringRef 中保存了字符串长度 Length 信息,所以在计算 strlen() 的时候可以节省一些时间,从而提升对长字符串计算长度时的性能。并且能够支持中间带有 null 字符的字符串。
* 配合 Twine 类,StringRef 的各类操做可能更有价值。code

* 然而我在代码中也看到过对 std::string 进行 StringRef 引用,然后在另外一个地方再次使用 str() 函数获得新分配的 std::string,这样不良的使用也会形成没必要要的屡次重复分配。有什么更好的办法来解决这种问题吗?
htm

相关文章
相关标签/搜索