字符串的几种实现方式

2021-03-27  本文已影响0人  wayyyy
eager copy
image.png
COW

此种实现方式为写时复制,即 copy-on-write。只有在某个 string 要对共享对象进行修改时,才会真正执行拷贝。

v2-f44c0fb3420c70efad85d8092c44d601_720w.jpg

需要修改时,才会拷贝。

v2-8446993f54365100c3c86c1d256f5b47_720w.jpg
短字符串优化
class sso_string
{
    char* start;
    size_t size;
    static const int kLocalSize = 15;
    union
    {
        char buffer[kLocalSize];
        size_t capacity;
    } data;
};

如果字符串长度比较短,那么直接存放在对象buffer里。

image.png

如果字符串超过15字节,那么就变成如下:

image.png
#include <string>
#include <new>
#include <cstdio>
#include <cstdlib>

int allocated = 0;

void *operator new(size_t sz)
{
    void *p = std::malloc(sz);
    allocated += sz;
    return p;
}

void operator delete(void *p) noexcept
{
    return std::free(p);
}

int main()
{
    allocated = 0;
    std::string s("length is 15   ");
    std::printf("length is 15 stack space = %d, heap space = %d, capacity = %d, size = %d\n",
                sizeof(s), allocated, s.capacity(), s.size());

    allocated = 0;

    std::string s2("length is 16    ");
    std::printf("length is 16 stack space = %d, heap space = %d, capacity = %d, size = %d\n",
                sizeof(s2), allocated, s2.capacity(), s2.size());
}

在我的环境:
gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
测试,输出:

length is 15 stack space = 32, heap space = 0, capacity = 15, size = 15
length is 16 stack space = 32, heap space = 17, capacity = 16, size = 16

说明确实是采用了短字符串优化。

注意capacity不包括Null ternimator,所以在堆上实际分配的大小为 capacity + 1

C++11 之后字符串实现变更

C++11之后实现的就是实时拷贝,因为C++11标准规定:不允许[]导致之前的迭代器失效,这就使得COW的string不再符合C++规范了。

FBString

TODO

上一篇 下一篇

猜你喜欢

热点阅读