map

title: Map Benchmark tags:

  • Benchmark

  • Map

    categories:

  • Data Structure

摘要

对如下map实现作benchmark:

  • standard map

  • standard hash map

  • google dense hash map

  • google sparse hash map

  • nark hash map

概念

google dense & sparse hash map

不同点

dense hash map

  • 查找速度快 ^[1]^

  • 使用之前,必须调用set_empty_key()函数设置empty bucket的key值 ^[1]^

sparse hash map

  • 空间开销小,每个entry占用1-2bit ^[1]^

相同点

  • 如果需要删除操作,必须调用set_deleted_key()函数设置deleted bucket的key值 ^[1]^

  • 在初始化时,插入元素的数量可以作为可选参数,相比于SGI的hash_map可以把桶的数量作为初始化时的可选参数 ^[1]^

  • erase()操作 ^[1]^

    • erase()操作不会立即释放内存,也不会导致哈希表的resize操作;相反,调用erase()会增加哈希表的内存占用 ^[2,3]^

    • erase()操作不会使迭代器失效,也就是说,下面代码合法

    • erase()操作不会减少哈希表的内存占用,其会在下次调用insert()函数时compact,但是可以通过调用resize()方法手动compact

    • resize(0)可以调整哈希表的size为最小的合法值 ^[2,3]^

  • sparse_hash_map::iteratorsparse_hash_map::iterator不是一个可变迭代器,因为sparse_hash_map::value_typedense_hash_map::value_type不能被赋值 ^[2,3]^

  • sparse_hash_mapdense_hash_map 必须是 plain old data ^[4,2,3]^

适用

dense hash map

  • 适用于需要快速访问存储在内存中的相对较小的“字典”的应用程序 ^[2]^

sparse hash map

  • 适用于需要在内存中存储大型“字典”的应用程序,以及需要这些字典持久化的应用程序 ^[3]^

底层数据结构

  • 基于二次探测的 hash table ^[1]^

nark hash map

特点

  • 使用两块连续内存 ^[5]^

  • 缓存hash value (hash key) ^[5]^

  • 删除元素更简单 ^[5]^

    • 直接将末尾元素拷贝到删除元素处

    • 删除元素时插入空闲链表,优先从空闲链表分配(id 不变)

底层数据结构

  • 基于开链的hash table ^[6]^

测试

环境

说明

实验在google item_hash_map.cc ^[7]^ 基础上进行修改,添加支持nark hash map(gold_hash_map),针对Hash Map的不同实现、Key的不同大小,指定迭代次数执行map的相关操作并进行耗时统计,对统计结果进行对比。

不同的Hash Map实现说明如下表所示。

名称

说明

sparse_hash_map

google sparse hash map

dense_hash_map

google dense hash map

unordered_map

standard hash_map

map

standard map

gold_hash_map

nark hash map

不同操作说明如下表所示。

操作

说明

map_grow

插入指定迭代次数元素

map_predict/grow

hash map初始化时指定元素数量为指定迭代次数,然后插入指定迭代次数元素

map_replace

替换指定迭代次数元素值

map_fetch_random

随机遍历hash map(元素数量为指定的迭代次数)

map_fetch_sequential

顺序遍历hash map(元素数量为指定的迭代次数)

map_fetch_empty

判断元素是否在map内(元素数量和循环次数为指定的迭代次数)

map_remove

删除所有元素(初始数量为指定的迭代次数)

map_toggle

添加一个元素,紧接着删除该元素(次数指定的迭代次数)

map_iterate

使用迭代器遍历map

迭代次数如下表所示。

Key大小(byte)

迭代次数

4

10000000

8

5000000

16

2500000

256

312500

实验共进行8组,结果参见链接 ^[8]^,示例结果参考附录,统计对应变量去除最大、最小值后的平均值,统计程序 ^[9]^ 见附录。

编译

编译命令如下。

结果

测试结果说明

key为4byte, map_grow操作,不同hash map实现的耗时对比。

测试结果

random fetch(find)

map_remove(erase)

fetch empty

map_fetch_sequential

map_grow

map_iterate

map_predict/grow

map_replace

map_toggle

参考

附录

耗时统计程序

time_hash_map示例输出

最后更新于