【问题标题】:How much memory does an initial empty unordered_map use?初始的空 unordered_map 使用多少内存?
【发布时间】:2022-12-29 09:18:36
【问题描述】:

如果我声明这样的哈希图:

std::unordered_map <int, int> m;

在我放入任何东西之前,实际上为地图分配了多少内存?

【问题讨论】:

  • 我相信这是实现定义的,但可能不是很多。多少对你来说太多了?
  • @user253751 如果构造函数在堆上分配,我会用 sizeof 看到吗?
  • 不,但在您将一些东西放入地图之前,构造函数可能不会分配。
  • @IsaacD.Cohen 我不知道,代码不可读(通常是标准库代码),再看一眼也许我错了

标签: c++ unordered-map


【解决方案1】:

它是实现定义的,但您可以结合使用 sizeof(对于 unordered_map 对象本身)和记录动态分配请求的自定义分配器策略来观察您正在使用的任何给定实现的内存使用情况。

我在 godbolt 上编写了代码 - https://godbolt.org/z/Yeoq4j1Pq - 只写了一个最小的自定义分配器,证明有必要让它在最新版本的 gcc、clang 和 msvc 下运行。下面的代码也供参考。

截至 2022/12/29,最新的 gcc 和 clang 显示 sizeof64,在插入完成之前不会向分配器请求额外内存,而 msvc 具有 sizeof 40 并且确实向分配器请求额外内存记忆即使是空的。

#include <unordered_map>
#include <iostream>
#include <utility>

template <typename T>
struct my_allocator {
    my_allocator() = default;
    template< class U >
    constexpr my_allocator( const my_allocator<U>& other ) noexcept { }
    using Base = std::allocator<T>;
    Base base;
    using value_type = typename Base::value_type;
    T* allocate(std::size_t n, const void* hint) {
        return allocate(n);
    }
    [[nodiscard]] constexpr T* allocate(std::size_t n) {
        std::cout << "allocate(" << n << ")
";
        return base.allocate(n);
    }
    constexpr void deallocate(T* p, std::size_t n) {
        base.deallocate(p, n);
    }
};

int main() {
    std::unordered_map<int, int, std::hash<int>, std::equal_to<int>, my_allocator<std::pair<const int, int>>> m;
    std::cout << "sizeof " << sizeof m << '
';
    for (int i = 0; i < 1; ++i)
        m[i] = i;
    std::cout << "buckets: " << m.bucket_count() << '
';
}

【讨论】:

    猜你喜欢
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 2011-04-17
    • 1970-01-01
    • 2013-07-27
    • 2020-10-20
    • 2019-06-20
    • 1970-01-01
    相关资源
    最近更新 更多