插入 unordered_map 需要太多时间
Inserting to unordered_map takes too much time
我编写了一个从文件中读取数字(大约 500,000 个)的程序,并将它们插入到数据结构中。数字是不同的。
我将数字插入到 unordered_map
和另一个结构(使用 std::make_pair(myNumber, emptyStruct))
.
在插入所有数字后,我只用它搜索了几百次。我从不删除 DS,直到程序完成 运行。
分析后,我注意到插入操作占用了 运行 时间的大约 50%。 (还有一些其他的代码,和插入一样运行多次,但是没那么多时间)。
我想也许调整大小需要时间,所以我使用了500,000的保留功能,但结果还是一样。
据我所知,这个DS应该是O(1)的插入和查找(折衷的是大内存),所以我不明白为什么插入要花这么多时间。我怎样才能改善我的结果?
无序映射是使用散列 table 实现的。它具有摊销常数插入时间。保留地图的大小有帮助,但不会太大。就插入而言,您无能为力。
这意味着您可能可以刮胡子一段时间,但这只是微不足道的。例如,插入一个向量稍微快一些,但它也是摊销常数时间。因此,您将以搜索为代价缩短插入时间。
这是数据库的帮助所在。假设您将数据保存在 sqlite 数据库中。您创建数据库,创建 table 并将搜索值作为其主键,并将数据值作为其其他属性,将这些值插入 table 一次。现在,该程序只是运行并查询数据库。它只读取必要的最低限度。在这种情况下,sqlite 数据库充当了您正在使用的无序映射的角色。
由于您没有特别使用值,而只是搜索存在,因此选择 std::unordered_set。当您为地图中的每个键创建一个虚拟值时,它会执行您想要的操作。
首先,我想重申一下大家所说的:插入500,000个项目来使用它几百次会占用你相当大的时间,而且你真的无法避免,除非你可以扭转局面 -- 构建一组您要搜索的内容,然后搜索 500,000 次。
综上所述,考虑到哈希表的性质,我能够在测试应用程序中插入 500,000 个项目方面取得一些改进:
查看 http://en.cppreference.com/w/cpp/container/unordered_map,我发现了这些:
[Insert] Complexity: Average case: O(1), worst case O(size())
By default, unordered_map containers have a max_load_factor of 1.0.
当您为 500000 个项目预留 space 时,您将获得 500000 个存储桶。如果将 500000 条数据放入 500000 个桶中,将会发生很多冲突。我预留了额外的 space,速度更快。
如果您确实需要速度,并且愿意出现一些错误,请查看布隆过滤器。
我编写了一个从文件中读取数字(大约 500,000 个)的程序,并将它们插入到数据结构中。数字是不同的。
我将数字插入到 unordered_map
和另一个结构(使用 std::make_pair(myNumber, emptyStruct))
.
在插入所有数字后,我只用它搜索了几百次。我从不删除 DS,直到程序完成 运行。
分析后,我注意到插入操作占用了 运行 时间的大约 50%。 (还有一些其他的代码,和插入一样运行多次,但是没那么多时间)。
我想也许调整大小需要时间,所以我使用了500,000的保留功能,但结果还是一样。
据我所知,这个DS应该是O(1)的插入和查找(折衷的是大内存),所以我不明白为什么插入要花这么多时间。我怎样才能改善我的结果?
无序映射是使用散列 table 实现的。它具有摊销常数插入时间。保留地图的大小有帮助,但不会太大。就插入而言,您无能为力。
这意味着您可能可以刮胡子一段时间,但这只是微不足道的。例如,插入一个向量稍微快一些,但它也是摊销常数时间。因此,您将以搜索为代价缩短插入时间。
这是数据库的帮助所在。假设您将数据保存在 sqlite 数据库中。您创建数据库,创建 table 并将搜索值作为其主键,并将数据值作为其其他属性,将这些值插入 table 一次。现在,该程序只是运行并查询数据库。它只读取必要的最低限度。在这种情况下,sqlite 数据库充当了您正在使用的无序映射的角色。
由于您没有特别使用值,而只是搜索存在,因此选择 std::unordered_set。当您为地图中的每个键创建一个虚拟值时,它会执行您想要的操作。
首先,我想重申一下大家所说的:插入500,000个项目来使用它几百次会占用你相当大的时间,而且你真的无法避免,除非你可以扭转局面 -- 构建一组您要搜索的内容,然后搜索 500,000 次。
综上所述,考虑到哈希表的性质,我能够在测试应用程序中插入 500,000 个项目方面取得一些改进:
查看 http://en.cppreference.com/w/cpp/container/unordered_map,我发现了这些:
[Insert] Complexity: Average case: O(1), worst case O(size())
By default, unordered_map containers have a max_load_factor of 1.0.
当您为 500000 个项目预留 space 时,您将获得 500000 个存储桶。如果将 500000 条数据放入 500000 个桶中,将会发生很多冲突。我预留了额外的 space,速度更快。
如果您确实需要速度,并且愿意出现一些错误,请查看布隆过滤器。