跨流行工具链的标准容器重新分配乘数

时间:2011-03-23 11:24:11

标签: c++ implementation containers

当内部容量耗尽时,std::basic_stringstd::vector等容器会执行自动重新分配。该标准规定,在重新分配后,.capacity() >= .size()

主流工具链在执行重新分配时使用了哪些实际乘数?


更新

到目前为止,我有:

  

Dinkumware:1.5(随MSVS发货,可能还有ICC)

     

GNU libstdc ++:2(GCC附带,可能还有ICC)

     

RW / Apache stdcxx:1.618

     

STLport:2

2 个答案:

答案 0 :(得分:4)

Dinkumware STL(随Visual Studio一起提供)使用1.5乘法器,Gcc使用2.我无法真正说出其余部分,但我认为这些是最常用的数字。 (IIRC,我曾读过大多数实现使用2)

作为旁注,你正确地称它为乘数,因为标准要求增长(至少)是几何的。

答案 1 :(得分:3)

旧问题的新答案。

理由:答案可以通过编程方式回答,也可以通过在线编译器相对轻松地回答。这是一个可以帮助您回答这个问题的程序:

#include <climits>
#include <cstddef>
#include <cstdlib>
#ifndef _MSC_VER
#   include <cxxabi.h>
#endif
#include <iostream>
#include <memory>
#include <string>
#include <typeinfo>
#include <type_traits>
#include <limits>
#include <vector>
#include <string>

template <typename T>
std::string
type_name()
{
    typedef typename std::remove_reference<T>::type TR;
    std::unique_ptr<char, void(*)(void*)> own
           (
#ifndef _MSC_VER
                abi::__cxa_demangle(typeid(TR).name(), nullptr,
                                           nullptr, nullptr),
#else
                nullptr,
#endif
                std::free
           );
    std::string r = own != nullptr ? own.get() : typeid(TR).name();
    if (std::is_const<TR>::value)
        r += " const";
    if (std::is_volatile<TR>::value)
        r += " volatile";
    if (std::is_lvalue_reference<T>::value)
        r += "&";
    else if (std::is_rvalue_reference<T>::value)
        r += "&&";
    return r;
}

template <class C>
void
test()
{
    C c;
    std::cout << type_name<C>() << ":\n";
    std::size_t c0 = c.capacity();
    std::cout << "    Initial capacity is " << c0 << '\n';
    c.resize(c0);
    for (int i = 0; i < 10; ++i)
    {
        c.push_back(typename C::value_type{});
        std::size_t c1 = c.capacity();
        if (c0 != 0)
        {
            float f = static_cast<float>(c1)/c0;
            std::cout << "    growth factor appears to be " << f << '\n';
        }
        c0 = c1;
        c.resize(c0);
    }
}

int
main()
{
    test<std::vector<int>>();
    test<std::string>();
}

大多数复杂性都有点不必要,因为它只是让type_name工作。

<强>的libstdc ++:

http://melpon.org/wandbox/permlink/njaIG2uiR2vlCLZz

对于矢量和字符串,

似乎都会回答实数2。

<强> VS

http://webcompiler.cloudapp.net

对于矢量和字符串,

非常接近1.5。

<强>的libc ++

http://melpon.org/wandbox/permlink/mXshrLJHgNuvE1mD

对于矢量和字符串,

非常接近2。

请注意,此程序还会告诉您string的短字符串缓冲区:libstdc ++和VS为15,libc ++为22。