Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.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++ 如何测量std::无序_映射的内存使用率_C++_Unordered Map - Fatal编程技术网

C++ 如何测量std::无序_映射的内存使用率

C++ 如何测量std::无序_映射的内存使用率,c++,unordered-map,C++,Unordered Map,我们知道基于散列表的容器实现像,但我不知道多少是多少 除了空间复杂性符号外,不考虑容器元素是否是指向较大对象的指针: 有没有办法计算出这样一个容器在运行时使用了多少字节 有没有办法在运行时判断一个容器使用了多少内存?如果你想得到一个大致的大小,我认为bucket\u count()和max\u load\u factor()就足够了,它给出了当前的bucket计数和负载系数 理性的: 如果load\u factor=映射中的项目,则bucket\u count()是内存使用量的大小 如果loa

我们知道基于散列表的容器实现像,但我不知道多少是多少

除了空间复杂性符号外,不考虑容器元素是否是指向较大对象的指针:

有没有办法计算出这样一个容器在运行时使用了多少字节


有没有办法在运行时判断一个容器使用了多少内存?

如果你想得到一个大致的大小,我认为
bucket\u count()
max\u load\u factor()
就足够了,它给出了当前的bucket计数和负载系数

理性的:

  • 如果
    load\u factor
    =映射中的项目,则bucket\u count()是内存使用量的大小

  • 如果
    load\u factor
    >1,则
    bucket\u count()
    *
    load\u factor
    指示地图中的最大项目。请注意,这是最大尺寸,而不是实际尺寸

因此,对于粗略的内存使用情况,可以如下所示:

  unsigned n = mymap.bucket_count();
  float m = mymap.max_load_factor();
  if (m > 1.0) {
    return n * m;
  }
  else {
    return n;
  }
如果要获得准确的内存使用率,可能需要对所有存储桶进行计数,以查看其中有多少个元素:

  size_t count = 0;
  for (unsigned i = 0; i < mymap.bucket_count(); ++i) {
    size_t bucket_size = mymap.bucket_size(i);
    if (bucket_size == 0) {
      count++;
    }
    else {
      count += bucket_size;
    }
  }
size\u t count=0;
for(无符号i=0;i
没有可移植的方法来判断使用了多少字节。您可以发现:

  • size()
    表示容器中插入了多少数据元素
  • bucket\u count()
    指示基础哈希表有多少个bucket,每个bucket都可以承载一个指向关联元素的链接列表
现在:

  • 实际用于元素存储的字节将是
    m.size()*sizeof(m::value\u type)

  • 哈希表存储桶使用的字节取决于内部列表的存储方式-
    std::unordered_map::bucket_size
    具有恒定的复杂性,因此我们可以合理地猜测每个存储桶将有一个
    size()
    和头指针,因此
    m.bucket_count()*(sizeof(size\u t)+sizeof(void*))
    是一个合理的猜测,尽管它可能是由于
    负载系数()
    是有界的,并且没有
    大小
    存储在每个存储桶中,因此只有恒定的摊销复杂性(我更愿意自己这样实现)

  • 如果插入的每个元素都是列表的一部分,那么它们将需要一个
    next
    指针,这样我们就可以添加另一个
    m.size()*sizeof(void*)

  • 每个内存分配可以四舍五入到一个便于内存分配库管理的大小-例如,下一个二次幂,接近100%的最坏情况无效率和50%的平均值,因此让我们为列表节点添加50%,因为存储桶可能是两个给定的
    size\t
    和一个指针的幂:50%*
    size()*(sizeof(void*)+sizeof((M::value\u type))

  • 特别是在调试模式下,可能存在任意数量的特定于实现的内务管理和错误检测数据


您可以通过创建大量大型表,并查看
top
或Process Manager如何报告不同的内存使用情况来进一步探索这一点。

这是一个有趣的问题,但听起来非常具体于实现。Valgrind或自定义分配器可能会起作用。@user657267一个参考或how to会很好。多少是多少?默认情况下,
un有序的容器的
max\u load\u factor
为1.0。当容器的
load factor
在一次操作中超过其
max\u load\u factor
时,容器会自动执行重灰烬。bucket\u size()不是只返回此bucket中的元素量吗?因此,您只需要获取容器的大小(),然后对每个未使用的铲斗增加一次。