【问题标题】:How could C++ Small String Optimized (SSO) work with containers?C++ Small String Optimized (SSO) 如何与容器一起工作?
【发布时间】:2016-12-11 12:40:02
【问题描述】:

SSO 解释说小字符串是在堆上分配的:好的,但是当在容器中构造时,这些内容不应该在堆栈上,因为容器可以在函数中创建并返回,而函数堆栈会过时。

所以我猜 SSO 不适用于 STL 容器,是吗?

【问题讨论】:

  • 确实如此。小字符串直接存储在 std::string 对象中。如果字符串扩展为大于允许的大小,则将它们重新分配给堆(指向来自 std::string 的指针)。

标签: c++ performance stl containers


【解决方案1】:

“小字符串”和“大字符串”的区别不在于将其存储在堆栈上还是堆上。相反,不同的是间接级别

这意味着std::string 对象可以保存一个指向实际字符串数据的指针,该指针可以是(几乎)任何长度,但具有间接动态内存的所有缺点 - 分配、解除分配、缓存未命中等。

另外,SSO 允许std::string 将小字符串“就地”存储在std::string 对象内,无论它被分配到哪里。如果对象在某个容器中(在堆上),那是字符串所在的位置,但它不会像大字符串那样需要另一个间接。

【讨论】:

    【解决方案2】:

    让我们以vectorstring 为例。

    1. 查看my answer to 'c++ Vector, what happens whenever it expands/reallocate on stack?',了解vector 通常的“外观”。

    2. 如果您将strings 存储在vector 中,则所有string 实例都将在堆上。

    3. 字符串实例本身可以

      • 在对象实例 (SSO) 中包含字符串数据本身或
      • 在堆上分配内存来存储内容。
    4. vector 类不关心 string 类存储其数据的位置。它只保存自己管理数据的对象。

    SSO 不会影响在容器中存储 strings。

    PS:您当然可以从函数中返回堆栈对象。函数堆栈将“超出范围”,但保留返回值。否则你甚至不能返回int

    SSO 并不意味着string 内容无论如何都在堆栈中。它只是意味着数据(小字符串)存储在string 实例中。如果实例在堆栈上,则数据在堆栈上。如果对象在堆上,那么数据也在堆上。

    【讨论】:

      【解决方案3】:

      您当然可以编写一个具有“小对象优化”的类向量类,如果对象很小且很少,它会将它们存储在内部(在容器对象本身内部),否则将它们存储在堆上(就像std::vector 现在所做的那样)。

      但是,目前标准库中的容器无法做到这一点,因为对它们提出了要求。特别是,[container.requirements.general]/9 说:

      在交换之前引用一个容器中的元素的每个迭代器在交换之后都应该引用另一个容器中的相同元素。

      小对象优化很难做到这一点,并且该要求不适用于basic_string

      【讨论】:

        猜你喜欢
        • 2017-08-27
        • 2014-03-29
        • 1970-01-01
        • 2020-01-06
        • 1970-01-01
        • 2022-01-06
        • 2017-05-09
        • 2014-06-10
        • 1970-01-01
        相关资源
        最近更新 更多