栈上字符串类 folly::FixedString

作者: , 共 1525 字

高效程序总是尽量避免频繁触碰在堆上分配和释放内存,所以无论是std::string还是folly:fbstring都做了SSO( small string optimization )。而folly::FixedString是一个很有意思的实现,它可以把任意长度的字符串都放在堆上。代码可见https://github.com/facebook/folly/blob/master/folly/FixedString.h

它很类似于char[N],以及std::array<char, N>。区别在于,它支持兼容std::string的大多数 API 和运算。比如下面实例:

using namespace folly::string_literals;
auto hello = "hello"_fs;                        // a FixedString<5>
auto world = "world"_fs;                        // a FixedString<5>
auto hello_world = hello + ' ' + world + '!';   // a FixedString<12>
folly::FixedString<24> more_space = hello_world;
more_space.replace(0, 5, "my");                 // more_space = "my world";

其内存布局非常简单直接:

tempalte<typename Char, size_t SIZE>
FixedString {
    Char data[SIZE + 1];        // 需要多一个字节存放\0。
    size_t size;                // 字符串实际长度。
};

其主要实现的黑科技是std::index_sequence,简单举个例子,它实现了从字符串地址构造一个FixedString对象:

constexpr BasicFixedString(const Char* that, size_t count) noexcept(false)
    : BasicFixedString{that, count, std::make_index_sequence<SIZE>{}} 
{}

template <class That, size_t... Is>
constexpr BasicFixedString(
    const That& that,
    std::size_t size,
    std::index_sequence<Is...>,
    std::size_t pos = 0,
    std::size_t count = npos) noexcept
    : data_{(Is < (size - pos) && Is < count ? that[Is + pos] : Char(0))...,
            Char(0)},
    size_{folly::constexpr_min(size - pos, count)} {}

Q. E. D.

类似文章:
编程 » C++, folly
folly::fbstring是一个完全兼容std::string的类,可以做到无缝替换,而且性能更高。其代码参见https://github.com/facebook/folly/blob/master/folly/FBString.h
编程 » folly, C++, 数据容器
由 Facebook 开发和维护的 C++库 Folly 提供folly::small_vector,代码文件地址:https://github.com/facebook/folly/blob/master/folly/small_vector.h
编程 » folly, C++, 数据容器
由 Facebook 开发和维护的 C++库 Folly 提供folly::sorted_vector_setfolly::sorted_vector_map,是std::mapstd::set在小数据集上的优化版。代码见: https://github.com/facebook/folly/blob/master/folly/sorted_vector_types.h
由 Facebook 开发和维护的 C++库 Folly 提供了锁folly::MicroLock,代码文件地址:https://github.com/facebook/folly/blob/master/folly/MicroLock.h
编程 » C++, 数据容器, folly
folly::dynamic提供类似于C++的动态类型。和std::any可以容纳任意类型不一样,folly::dynamic只支持保存以下几种类型:
由 Facebook 开发和维护的 C++库 Folly 提供了自旋锁的实现folly::MicroSpinLock,代码文件地址:https://github.com/facebook/folly/blob/master/folly/synchronization/MicroSpinLock.h
编程 » C++, 智能指针
前面已经提到std::shared_ptr有三个缺陷:
编程 » C++, C++标准库
std::tuple的原理并不复杂,但有些细节非常有意思。其中有一个是至少在gnu C++ std的实现中,std::tuple是倒序存储的:
由 Facebook 开发和维护的 C++库 Folly 提供了锁folly::MicroLock,代码文件地址:https://github.com/facebook/folly/blob/master/folly/MicroLock.h
编程 » C++, gcc
follyLikely.h文件提供了 LIKELY 和 UNLIKELY 宏,提示编译器在分支预测时选择分支。其实现很简单