Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 无序_映射Vs映射Vs数组-内存分析_C++_Std - Fatal编程技术网

C++ 无序_映射Vs映射Vs数组-内存分析

C++ 无序_映射Vs映射Vs数组-内存分析,c++,std,C++,Std,正如标题所说,我想知道无序映射、映射和数组之间的内存差异 例如: unordered_map <long long , int> a; map <long long , int> b; long long c[1000000]; a和b有1000000个存储元素 我想让它尽可能简单。我在网上搜索,没有找到正确的答案。我发现map和unordered_map比数组占用更多内存,但我不知道如何处理它 编辑:如何处理内存差异,例如如果我存储完全相同的2个元素,内存差异是什么。

正如标题所说,我想知道无序映射、映射和数组之间的内存差异

例如:

unordered_map <long long , int> a;
map <long long , int> b;
long long c[1000000];
a和b有1000000个存储元素

我想让它尽可能简单。我在网上搜索,没有找到正确的答案。我发现map和unordered_map比数组占用更多内存,但我不知道如何处理它


编辑:如何处理内存差异,例如如果我存储完全相同的2个元素,内存差异是什么。

因为C++11标准库容器支持有状态分配器:您可以传递一个分配器类型,它记录分配的数据量并跟踪最大使用量。您还需要考虑对象大小,因为对于数组,实际上没有分配器,因为数组是内置实体

例如:

#include <iostream>
#include <functional>
#include <memory>
#include <map>
#include <unordered_map>
#include <vector>

using namespace std;

static constexpr long total_size = 1000000;

template<typename T>
class CountingAllocator
{
public:
    shared_ptr<size_t> d_max = make_shared<size_t>(0u);
    using value_type = T;
    using pointer = T*;

    CountingAllocator() = default;
    template <typename S>
    CountingAllocator(CountingAllocator<S> const& other): d_max(other.d_max) {}
    size_t size() const { return *d_max; }
    T* allocate(size_t size) {
        size *= sizeof(T);
        *d_max += size;
        return reinterpret_cast<T*>(operator new(size));
    }
    void deallocate(void* ptr, size_t) {
        operator delete(ptr);
    }
    friend bool operator== (CountingAllocator const& c0, CountingAllocator const& c1) {
        return c0.d_max == c1.d_max;
    } 

    friend bool operator!= (CountingAllocator const& c0, CountingAllocator const& c1) {
        return !(c0 == c1);
    }
};

template <typename T>
void size(char const* name) {
    CountingAllocator<typename T::value_type> allocator;
    T m(allocator);
    for (int i = 0; i != total_size; ++i) {
        m[i] = i;
    }
    cout << name << "="  << allocator.size() << "\n";
}

int main() {
    size<map<long, long long, less<int>, CountingAllocator<pair<long const, long long>>>>("map");
    size<unordered_map<long, long long, hash<long>, equal_to<long>, CountingAllocator<pair<long const, long long>>>>("unordered_map");
    cout << "array=" << sizeof(long long[total_size]) << "\n";
    return 0;
}

当然,阵列的占用空间最小,每个元素的开销为零。我感到惊讶的是,无序_图的平均每元素开销比map小。除了数据外,使用5个单词似乎有点过分。

我不知道如何处理它。具体如何处理?内存映射和无序映射使用了多少内存是一个实现细节。如果你想用大O表示法,那么它们都是等价的。你可以实现一个自定义的。它被指定为模板参数,例如std::vector.c当然应该是最小的,因为它存储了一半的数据。它存储1000000个long-long实例,而a和b存储的long-long实例加上1000000个long-long实例int@IgorTandetnik是的,但我知道存储了哪些元素,它们是相同的。在许多情况下,这种分析可能低估了地图的实际内存消耗。底层内存管理器可能会为通过new operator分配的指针返回32或64字节对齐的地址,因此映射中的节点不会花费40/48字节,而是64字节。@ead:是的,此分析仅计算数据结构实际需要的内容。任何额外的维护都将是最重要的。当然,使用合适的分配器可以降低开销,例如,通过维护与请求大小完全匹配的缓冲池。
map=          48000000
unordered_map=40654880
array=         8000000