уменьшение числа маленьких аллокаций при использовании make_shared уже существенный плюс
для примера уйдем в другую крайность, множество маленьких аллокаций и ни одного weak_ptr
#include <iostream>
#include <chrono>
#include <list>
template<class T, class F>
auto test(F&& create)
{
std::list<std::shared_ptr<T>> set;
auto max = std::numeric_limits<size_t>::max();
for (size_t count = 0; count < max - 1; ++count)
{
try
{
set.emplace_back(create(count));
}
catch (const std::bad_alloc&)
{
return count;
}
}
return max;
}
int main(int argc, char *argv[])
{
using namespace std::chrono;
using type = int;
if (argc == 1)
{
auto start = steady_clock::now();
auto val = test<type>([](auto val) { return std::make_shared<type>(val); });
auto end = steady_clock::now();
std::cout << "make_shared | count: " << val << ", time: " << duration_cast<milliseconds>(end - start).count() << "msc\n";
}
else
{
auto start = steady_clock::now();
auto val = test<type>([](auto val) { return new type(val); });
auto end = steady_clock::now();
std::cout << "new | count: " << val << ", time: " << duration_cast<milliseconds>(end - start).count() << "msc\n";
}
}
вариант с make_shared делает 2 аллокации на элемент, вместо трех, позволяя эффективнее использовать память
на моем компе x86 вариант с make_shared размещает на треть элементов больше)
PS. тестить лучше в разные запуски
например если в аллокаторе не указан propagate_on_container_swap как true_type
и отдельный гемор если нужно передавать аллокатор «в глубь» контейнера
c 17го стандарта лучше смотреть в сторону en.cppreference.com/w/cpp/memory/polymorphic_allocator
для примера уйдем в другую крайность, множество маленьких аллокаций и ни одного weak_ptr
вариант с make_shared делает 2 аллокации на элемент, вместо трех, позволяя эффективнее использовать память
на моем компе x86 вариант с make_shared размещает на треть элементов больше)
PS. тестить лучше в разные запуски
так лучше не делать, в c++17 не просто так задеприкейтили половину функций в std::allocator
в конструкторе unordered_map происхоит усечение до std::allocator, в котором нет ни одной виртуальной функции
см.
en.cppreference.com/w/cpp/memory/allocator_traits
если уж хочется от чего-то унаследоваться см.
en.cppreference.com/w/cpp/memory/memory_resource
en.cppreference.com/w/cpp/memory/polymorphic_allocator
можно не переименовать, т.к. func слева от = в захвате относится к неймспейсу лямбды