unordered_map存储桶的节点大小

时间:2019-01-08 20:08:36

标签: c++ unordered-map memory-alignment

我有一个程序,要存储kmers(大小为k的子字符串)及其出现的次数。对于此特定应用程序,我正在读取具有这些值的文件,并且如果它们出现的次数大于255,则可以四舍五入为255。我认为如果将键值对存储为(string (无符号字符),与将键值对存储为(string,int)相比,可以节省空间,但是当我通过运行/ usr / bin / time检查最大驻留大小时,情况似乎并非如此。

为确认,我还尝试运行以下测试程序,在其中替换了unordered_map中值的类型:

pygal

这似乎并没有影响存储桶中节点的大小(在我的机器上,未签名的char和int值均返回40)。

我想知道如何确定每个存储桶中节点的大小。

我对无序映射的理解是,c ++标准或多或少需要单独的链接,并且存储桶中的每个节点都必须至少具有一个指针,以便元素可迭代并可以擦除(http://bannalia.blogspot.com/2013/10/implementation-of-c-unordered.html)。但是,我不知道如何确定存储值的空间量,而且看起来还必须灵活以容纳更大的值。我还尝试查看gcc libstc ++ unordered_map标头(https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/unordered_map.h),但很难理解发生了什么。

1 个答案:

答案 0 :(得分:1)

编译并执行以下代码:

#include <iostream>
#include <unordered_map>
#include <utility>
#include <string>
#include <fstream>

class foo
{
   std::string kmer;
   unsigned char abun;
};

class bar
{
    std::string kmer;
    int abun;
};

int main() {
    std::cout << sizeof(foo) << " " << sizeof(bar) << std::endl;
}

我明白了,40 40你也可能会明白。这是由于对齐要求。例如,如果std::string包含至少一个指针(几乎可以肯定如此),则它必须在至少4个字节的边界上对齐。

想象一下,如果sizeof(foo)是39,并且您有执行foo foos[2]的代码。如果foos[0].kmer中的指针正确对齐,则foos[1].kmer中的指针将不会对齐。那将是一场灾难。