我有多个项目由其二维坐标(有符号的短距离)标识。每个项目都是包含64KB数据的类。随时有大约500-1500件物品。物品通常在一个点左右~20组。我的问题是我应该如何映射它们以便它不会占用太多内存。项目将被缓慢添加/删除(每秒1-10次)并且将经常被提取,因此从列表中获取元素(指向更大结构的指针)应该尽可能快。
我想到的是会有一些gridContainer类让我们说它会存储64x64指针的矩形。我将有主网格容器,它将存储其他gridContainer,这个嵌套的gridContainer将存储我想要映射的实际项目(这将允许4096x4096实际项目)。要访问特定项目,例如[260,130],我将其除以64并使用商来查找父gridContainer位置和余数以查找嵌套的gridContainer位置。所以对于[270,145],我会[4,2]和[14,17]。
我也在考虑使用std::map
,但我不知道它的内部结构,我不知道我应该从中得到什么性能。
对我的方法有任何建议或有更好的方法吗?
答案 0 :(得分:2)
您可以使用已建议的std :: map,它只是一个b树容器,或者您可以使用哈希表,它可能更快。四叉树也是一种选择,它比前两个选项更复杂,但会提供早期选项。
具有最小负载的哈希表很有可能成为O(1)查找,但是当n =项目存在时,具有O(n)的最坏情况。如果你可以将负载保持在10%以下,那么你必须有一个非常可怕的散列函数才能比O(1)更糟糕。这显然会扼杀许多额外的内存,但它有可能成为最快的选择。哈希表的比较类型非常复杂。你有一个hasher函数接受键类型的输入,在这种情况下是一对short,并返回一个索引。该索引对应于半固定对象数组上的位置。如果那里已有一个物体,则必须解决碰撞,这可能导致不利的运行时间,因此越稀疏越好。
四叉树的最佳情况返回时间为O(1),但仅适用于空单元格,而如果存在一个项目,则其查找时间为O(log n),其中n是所需的大小领域。除非你的对象很少,否则它有可能占用比哈希表更多的内存,但如上所述,你得到一个不错的运行时间,并且产生没有结果的查找可以以相对速度终止。 Quad树的比较类型通常只是一个级联布尔检查。
std :: map的查找时间常数为O(log n),其中n是地图中的元素。这是内存效率最高的选项,但可以保证任何查找的运行时间。 std :: map的比较类型是级联小于操作,在int((short1<< 16)| short2)的情况下,也非常快。
您可能会使用的容器有一个很好的概述。你应该使用的那个取决于你期望你的桌子的装载量。只有几个对象(< 500),std :: map可能是你最好的选择。对于500到大约5000,您应该使用四叉树。除此之外,你将开始为树使用大量的内存,而应该使用哈希表。
答案 1 :(得分:1)
您可以随时使用std::map<std::pair<short, short>, *item>
,这样可以在log(n)
时间内检索和添加,但要获得更准确的答案,我们必须知道您需要快速执行哪些操作
答案 2 :(得分:1)
Quad Tree似乎就是你要找的。 p>