跨流行工具链的标准容器重新分配乘数 [英] Standard container re-allocation multipliers across popular toolchains

查看:111
本文介绍了跨流行工具链的标准容器重新分配乘数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



在执行重新分配时,主流工具链使用的一些实际的乘数是多少?






更新



到目前为止,我有:


Dinkumware:1.5(附带MSVS和可能的ICC)



GNU libstdc ++:2(附带GCC和可能的ICC)



RW / Apache stdcxx:1.618



STLport:2





原因:答案可以用程序来回答,并且使用在线编译器,相对容易。以下是一个可以帮助您回答此问题的程序:

  #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;
}

模板< class C>
void
test()
{
C c;
std :: cout<< type_name< C>()<< :\\\
;
std :: size_t c0 = c.capacity();
std :: cout<< 初始容量为< c0<< '\\\
';
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<< 生长因子似乎是< f<< '\\\
';
}
c0 = c1;
c.resize(c0);
}
}

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

大多数复杂性是有点不必要的,因为它只是得到<$



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

$



VS:



http://webcompiler.cloudapp.net

$
$ b

对于向量和字符串都非常接近1.5。



libc ++
$ b

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

注意,这个程序也会告诉你什么短字符串缓冲区为 string :15用于libstdc ++和VS,22用于libc ++。


Containers like std::basic_string and std::vector perform automatic re-allocations when internal capacity runs out. The standard specifies that, after a re-allocation, .capacity() >= .size().

What are some of the actual multipliers used by mainstream toolchains when performing re-allocations?


Update

So far, I have:

Dinkumware: 1.5 (ships with MSVS and possibly ICC)

GNU libstdc++: 2 (ships with GCC and possibly ICC)

RW/Apache stdcxx: 1.618

STLport: 2

解决方案

New answer for an old question.

Rationale: The answer can be answered programatically, and with online compilers, relatively easily. Here is a program that can help you answer this question:

#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>();
}

Most of the complexity is a bit unnecessary as it is just to get type_name working.

libstdc++:

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

appears to answer a solid 2 for both vector and string.

VS:

http://webcompiler.cloudapp.net

is very close to 1.5 for both vector and string.

libc++

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

is very close to 2 for both vector and string.

Note that this program also tells you what the short string buffer is for string: 15 for both libstdc++ and VS, and 22 for libc++.

这篇关于跨流行工具链的标准容器重新分配乘数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆