地图的大小比矢量好
At what size is map better than vector?
我有一个对象集合,每个对象都有一个标识符(字符串)。现在我想知道我应该把它们存储为向量还是映射,所以要么是std::vector<cObject>
,要么是std::map<std::string,cObject>
。每个名称只能使用一次,所以我需要检查向量/映射是否存在给定名称。使用映射时,我会使用对数缩放的find(),而对于向量,我会迭代并测试oObject.name == newname
,直到找到名称或到达末尾,这是线性缩放的。映射的缺点是名称存储两次,一次存储在对象内部,一次作为关键字。
虽然对于大型矢量/地图,地图总是会获胜,但我想知道在哪一点上是这样的,因为如果我只有多达10个对象要存储,那么地图似乎太夸张了。
这就引出了我的问题:与普通向量相比,映射在哪一点上(在性能方面)变得有利?如果预期的对象数量大约是10、100、1000甚至更大,我是否应该考虑使用地图?我承认这个问题相当模糊,但我希望无论如何都能得到一些建议,以了解何时使用哪个容器。
很难预测映射比矢量更有利的大小。但有几点你可以考虑:
- 映射基本上实现为二叉树,而向量实现为数组。因此,当有10到12个元素时,在数组中迭代比较容易,因为这将是一个线性搜索
- 映射比矢量快的点取决于处理器上的实现,以及你试图在其中存储的数据。我的最佳猜测是,5-20个元素的映射会更快。(但这只是一个猜测,我建议你为自己创建一个基准)
- "默认情况下,当你需要一个容器时,使用向量"-Bjarne Stroustrup
您还可以发现这个C++容器备忘单非常有用
这取决于矢量和映射的实现方式,以及代码对它们执行的操作(例如,将元素添加到中间或末尾、删除元素、重复添加和删除等)。您需要测试和评测您的代码。即使是它们,答案也将取决于主机系统(例如缓存、流水线等)。
顺便说一句,如果对向量进行排序,则查找元素也会按对数缩放(例如,使用二进制搜索)。因此,你的比较基础(矢量线性,映射对数)是有缺陷的。
使用映射时,我会使用对数缩放的find(),而对于向量,我会迭代并测试oObject.name==newname,直到找到名称或到达末尾,这是线性缩放的。
不完全正确,您可以对向量中的对象进行排序,并使用对数复杂度的std::binary_search
。
映射的缺点是名称存储两次,一次存储在对象内部,一次作为关键字。
您可以将std::set
与自定义比较器一起使用,这样您就不必单独存储密钥。
总的来说,Knuth说"过早的优化是万恶之源"。让你的程序可读,使用更容易的方法(我想是std::map
或std::unordered_map
),如果你对这个容器有性能问题,以后再优化它。将这个容器封装在某个类中可能会很有帮助,所以以后你可以透明地替换其余代码的实现。
- 为什么不;名字在地图上是按顺序排列的吗
- 基于多个条件处理地图中的所有元素
- 在C++中将矢量转换为嵌套地图
- 替换基于地图的所有引用
- 如何区分地图中的 0 和 false?
- 地图计数确实很重要,或者只是检查是否存在
- 如何从地图中删除矢量对象
- 是否有任何C++功能可以对地图进行排序?
- 如何使用 std::variant 打印地图键/值?
- 从矢量或地图中删除共享指针
- 在 c++ 中,有一种方法可以创建一个包含地图作为值的树状地图?
- 无限嵌套具有变体的地图
- C++一会儿循环读到地图上 2 行?
- 如何在cpp中使用地图显示给定日期范围内(在下面的问题中)的费率?
- 如何检查变量是否是C++中的地图?
- 如何使地图按值C++排序
- 修改地图内矢量中的值
- 为什么我在地图中搜索STL时差很大?
- 我正在尝试按降序对地图进行排序,但没有得到预期的结果?
- 如何包装(撰写)增强 hana 地图并访问括号运算符(运算符 [])?