我有一组对象,每个对象都有一个标识符(字符串)。现在我想知道是否应该将它们存储为矢量或地图,因此std::vector<cObject>
或std::map<std::string,cObject>
。每个名称只能使用一次,因此我需要检查向量/映射是否存在给定名称。使用地图,我会使用以对数方式进行缩放的find(),而对于向量,我会迭代并测试oObject.name == newname
,直到找到名称或到达末尾,线性缩放。地图的缺点是名称存储两次,一次存储在对象内,一次存储为密钥。
对于大型矢量/地图,地图总会赢,我想知道在哪种情况下,因为如果我最多只有10个对象要存储,地图似乎有点过分。
这导致了我的问题:与普通矢量相比,地图在哪一点上变得有利(关于性能)?如果预期的对象数量大约是10,100,1000甚至更大,我是否应该考虑使用地图?我承认这个问题相当含糊,但我希望能得到一些建议,以便了解何时使用哪个容器。
答案 0 :(得分:3)
很难预测地图有利于矢量的大小。但是你可以考虑几点:
您可能还会发现此C++ Containers Cheat Sheet有用
答案 1 :(得分:1)
这取决于向量和映射的实现方式,以及代码对它们执行的操作(例如,向中间或末尾添加元素,删除元素,重复添加和删除等)。您需要测试并分析您的代码。即便是这样,答案也取决于主机系统(例如缓存,流水线等)。
顺便提一下,如果你对矢量进行排序,找到一个元素也会以对数方式进行缩放(例如使用二进制搜索)。因此,您的比较基础(矢量线性,地图对数)是有缺陷的。
答案 2 :(得分:1)
使用map,我会使用以对数方式缩放的find(),而对于vector,我会迭代并测试oObject.name == newname,直到找到名称或到达末尾,这会线性缩放。
不完全正确,您可以将对象保持在向量中,并使用具有对数复杂度的std::binary_search
。
地图的缺点是名称存储两次,一次存放在对象内,一次存储为关键字。
您可以将std::set
与自定义比较器一起使用,这样您就不必单独存储密钥了。
总的来说Knuth说“过早优化是万恶之源”。让您的程序可读,使用更简单的方法(我猜std::map
或std::unordered_map
)以及稍后如果您对此容器存在性能问题进行优化。将此容器封装在某个类中可能会有所帮助,因此稍后您可以透明地替换其余代码的实现。