Стандартные множители перераспределения контейнеров в популярных наборах инструментов
Контейнеры как std::basic_string
а также std::vector
выполнять автоматическое перераспределение при исчерпании внутренней емкости. Стандарт определяет, что после перераспределения .capacity() >= .size()
,
Каковы некоторые из фактических множителей, используемых основными инструментальными цепочками при выполнении перераспределений?
Обновить
Пока что у меня есть:
Dinkumware: 1.5 (поставляется с MSVS и, возможно, ICC)
GNU libstdC++: 2 (поставляется с GCC и, возможно, ICC)
RW / Apache stdcxx: 1.618
STLport: 2
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;
}
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
: 15 для libstdC++ и VS, и 22 для libC++.
Dinkumware STL (поставляется с Visual Studio) использует множитель 1,5, Gcc использует 2. Я не могу сказать, в остальном, но я думаю, что это наиболее часто используемые числа. (IIRC, я прочитал однажды, что большинство реализаций использовали 2)
В качестве дополнительного комментария вы правильно называете его множителем, поскольку стандарт требует, чтобы рост был (как минимум) геометрическим.