C++ 堆与读取映射最左侧节点的相对性能?

C++ 堆与读取映射最左侧节点的相对性能?,c++,c,data-structures,C++,C,Data Structures,假设你是一个批发商,你的顾客中有顾客。交易是由客户的客户完成的,但当您看到每笔交易时,您只需向客户开具账单,只需担心客户的存款耗尽。这是一项预付费服务 事务用于服务,其值是服务持续时间*速率的函数 我需要一种方法,通过汇总客户累积的费用,来监控我的客户的0万个账户的存款耗尽情况。我与客户的客户没有财务安排 当给定服务实例启动时,我的客户的BurnRate会随着任何给定服务的收费率添加到代表我的客户提供的所有过程中服务的累积费率中而增加。当服务终止时,燃烧率也同样降低 一个很好的候选者似乎是,或者

假设你是一个批发商,你的顾客中有顾客。交易是由客户的客户完成的,但当您看到每笔交易时,您只需向客户开具账单,只需担心客户的存款耗尽。这是一项预付费服务

事务用于服务,其值是服务持续时间*速率的函数

我需要一种方法,通过汇总客户累积的费用,来监控我的客户的0万个账户的存款耗尽情况。我与客户的客户没有财务安排

当给定服务实例启动时,我的客户的BurnRate会随着任何给定服务的收费率添加到代表我的客户提供的所有过程中服务的累积费率中而增加。当服务终止时,燃烧率也同样降低

一个很好的候选者似乎是,或者,但是我想到传统的树/映射也可以工作,因为最左边的节点,即从迭代器读取的第一个节点,将产生相同的信息

至少有可能N个客户可能有完全相同的存款耗尽时间,也就是生存时间(TTL),计算为“现在”+(CurrentBalance/BurnRate),因此多重映射可能比堆更合适。同样,任何基于经验的见解都会非常有用

我的主要问题是堆或map/multimap哪个性能更好? 第二,堆能否优雅地处理重复的值

TVMIA提供任何性能洞察力,特别是从经验或基准测试中

PS:回顾文献,我省略了一个重要的要求。当启动新服务或过程中服务结束时,我必须用删除客户的旧TTL节点来更新数据结构,并用新TTL插入一个新节点优先级队列似乎不支持这些操作。

也在第31章第924页的C++编程语言第四版中,StruouTutp强烈暗示使用PrrordyIQueQueLILE实现树是首选方法。由于我上面提到的“oops”需求只能通过一棵树来满足,所以我的选择是明确的,所以不会进行基准测试来比较这两种方法——至少在这个项目完成之前是这样


感谢所有参与(或潜伏)并分享其知识和经验的人

由于没有提供实际的数据/架构,因此只能讨论理论

让我们首先定义正在使用的3个选项:

根据您提供的链接,这似乎是一个排序的
向量

根据OP中的用法,它是
std::map
,可以认为是红黑树

散列通常,这称为散列映射,已作为
std::无序映射

我们将忽略一个或多个有效负载(map与multimap),因为性能应该不会有太大差异

由于我们讨论的是许多数据点,因此我们可以查看预期的最长时间。我们还可以查看摊销平均时间,因为您没有提到响应时间限制,但更多的是吞吐量限制

必须首先查看的3个操作是,插入,删除和查找(实际上没有提到随机访问的要求)

对于每个集合/操作:将列出平均复杂度/最大复杂度

collection   insert       delete     first
heap         N/N^2        N/N        1/1
tree         log N/log N  1/1        log N/log N
hash         1/N^2        1/N        1/N
注意,有两个问题

  • 如果碰撞过多,所有操作都会变成线性

  • 插入可能需要存储阵列增长

堆有两个问题

  • 插入和删除可能会导致大多数数据元素发生移动

  • 插入可能需要向量增长

在这些数据结构中,hash似乎具有尽可能好的性能,偶尔会出现非常糟糕的性能影响。如果这可以摊销(与最差性能相对的平均值至关重要),则使用散列,否则对于最差情况下的最佳性能map最接近于满足要求。如果插入/删除时间不是关键时间,并且可以避免影响首次查找,堆将是最快的,并且可能提供最佳的位置


而且,如前所述,您确实应该首先对正在考虑的所有解决方案进行概要分析/压力测试

:对其进行概要分析。找出答案对于世界上每一台不同的计算机都是独一无二的。第二:优雅地定义为处理重复数据的堆。树的内存性能比哈希表差(注意,我说的是哈希表,不是std::map。map是一个树),因为缓存未命中。在一个常见的用例中,我认为很难感觉到任何性能问题,但您谈论的是数百万客户。这可能是一个需要考虑的细节。此外,树的复杂性为O(logn),哈希表的复杂性为O(1)。同样,在一个普通(小)用例中,O(logn)的“伪相等”为O(1)(注意log(1000)是3)。但在你的情况下。。。数十亿…@Manu343726,谢谢你的回复,但我必须知道使用哈希所需的哈希表的大小。我的应用程序不允许这样做,因此树是唯一合理的选择。提醒一下,O(1)不一定比O(logN)快。这些指标并不表示绝对性能,只指定性能如何随搜索集的大小而变化。IE:未指定方法之间的比较,仅说明作为增长函数的性能。这就是散列比树慢的原因,在我的例子中,它们不是一个选项。你是对的。我只是指出,在大型用例中(如您的情况),成本会增加。但这是真的,不是