在std :: string的上下文中,首字母缩略词SSO的含义?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (12)

SSO意味着什么?

提问于
用户回答回答于

背景/概述

对自动变量(“来自堆栈”的操作,这些变量是您在不调用malloc/的情况下创建的变量new)通常比涉及免费商店(“堆”,即使用创建的变量)的操作要快得多new。但是,自动数组的大小在编译时是固定的,但免费商店中的数组大小不是。此外,堆栈大小是有限的(通常是几个MiB),而免费存储只受系统内存限制。

SSO是短/小字符串优化。A std::string通常将字符串存储为指向免费商店(“堆”)的指针,该指针具有与您打电话时相似的性能特征new char [size]。这可以防止非常大的字符串发生堆栈溢出,但速度会更慢,特别是在复制操作时。作为一个优化,许多实现std::string创建一个小的自动数组,类似char [20]。如果您有一个不超过20个字符的字符串(给定此示例,实际大小会有所不同),则会将其直接存储在该数组中。这样可以避免需要调用new,这会加快速度。

实施细节

至少std::string需要存储以下信息:

  • 尺寸
  • 容量
  • 数据的位置

大小可以存储为一个std::string::size_type或作为指向末尾的指针。唯一的区别是当用户调用时是否需要减去两个指针,size或者是否需要在用户调用时将指针添加size_type到指针end。容量也可以以任何方式存储。

你不支付你不使用的东西。

首先,考虑基于我上面概述的天真实施:

class string {
public:
    // all 83 member functions
private:
    std::unique_ptr<char[]> m_data;
    size_type m_size;
    size_type m_capacity;
    std::array<char, 16> m_sso;
};

对于64位系统,这通常意味着std::string每个字符串有24个字节的“开销”,另外还有16个用于SSO缓冲区(由于填充要求,此处选择16个而不是20个)。如我的简单示例中那样存储这三个数据成员以及一个本地字符数组是没有意义的。如果m_size <= 16,那么我会把所有的数据都放进去m_sso,所以我已经知道了容量,而且我不需要指向数据的指针。如果m_size > 16,那么我不需要m_sso。在我需要所有这些元素的地方绝对不会有重叠。没有空间的智能解决方案看起来会更像这样(未经测试,仅用于示例目的):

class string {
public:
    // all 83 member functions
private:
    size_type m_size;
    union {
        class {
            // This is probably better designed as an array-like class
            std::unique_ptr<char[]> m_data;
            size_type m_capacity;
        } m_large;
        std::array<char, sizeof(m_large)> m_small;
    };
};

我假设大多数实现看起来更像这样。

用户回答回答于

SSO是“小字符串优化”(Small String Optimization)的缩写,一种将小字符串嵌入字符串类的主体而不是使用单独分配的缓冲区的技术。

扫码关注云+社区