拥有地图地图或非常大的地图会更有效吗?

时间:2011-09-29 02:12:54

标签: c++ map

我在map中存储了一些对象(用字符串散列),但是对象可以用另一个字符串分类。 因此,我可以制作这些类别的地图,并为每个类别保留该类别中对象的另一个地图。

每当我从此数据结构进行插入或获取请求时,我将始终知道该类别。 这更有效吗?看起来它会是这样,除了地图的查找时间是log(n)我相信,那么总体收益会是什么呢?

3 个答案:

答案 0 :(得分:5)

使用真实数据测试更快的速度。

诸如“地图的查找时间是log(n)”之类的语句可能会产生误导。还有一个随意的渐近常数。此外,如果您以非均匀随机方式分发数据或数据访问,通常情况下,关于“最佳”的陈述会变得更加复杂。

在性能方面,很少有比使用实际数据的实际测量更好的工作。

答案 1 :(得分:3)

“这样效率更高吗?好像是”

我的直觉说,在一般情况下,由于两个原因效率会降低。

首先,您要添加更多密钥。您需要搜索n1个对象。您还有n2个对象被分为的类别。你现在有n1 + n2个键而不是n1。

其次,std :: map通常实现为平衡二叉树。平衡部分对于确保最坏情况查找时间为O(log n)而不是O(n)至关重要。通过移动到两层结构,您可能会阻止树平衡。如果您对对象的访问是随机均匀的,那么不平衡树的性能将比平衡树差。

为了说明一个完美平衡的树。最糟糕的案例3比较。

       d
     /   \
   b       f
  / \     / \
 a   c   e   g

具有相同数据的不平衡树。最坏情况4比较。

    b 
  /   \
a       e
       / \
      d   f
     /     \
    c       g

也就是说,如果您要搜索的内容靠近树顶,则不平衡树可以更快。这就是为什么你应该听@nsanders说话的原因。

答案 2 :(得分:1)

执行算术运算,如果有n个元素,则查找时间为O(log(n))。如果将地图拆分为包含大小为m2的地图的m1地图,则需要在第一个地图中查找O(log(m1)),然后在第二个地图上执行O(log(m2))查找。但是从那以后

log(m1) + log(m2) = log(m1*m2) = log(n)

你不是以任何一种方式购买,你应该以最能表达你意图的方式对其进行编码。

就实际表现而言,您应该对其进行分析,看看它是否有所作为。这两个映射可能会更快,因为每个映射都有一个更简单的比较器函数(它们每个都会进行一次字符串比较,而单片映射的比较器对于某些对对象必须做两次)。此外,如果在您的应用程序中,您可能无法在第一个字符串中找到大量查找的匹配项,那么您将只进行第一次查找,这可能会节省一些时间。

另一方面,如果辅助地图的大小不均匀,那么您可以有效地进行两次查找。在最坏的情况下,考虑到一半的键具有相同的第一个字符串,而其他键都具有区域字符串。