【问题标题】:Is there a efficient way to search a key in queue and override its value?有没有一种有效的方法来搜索队列中的键并覆盖它的值?
【发布时间】:2020-03-01 10:38:37
【问题描述】:

我正在使用 C++ 编写一个应用程序,其中我需要实现一个消息队列,该队列将不断地从网络接收数据(即对象),每个对象都有一个键(例如公司名称,比如 Oracle、Google 等)。如果队列消费者速度较慢,我可以在队列中拥有大量元素(最大限制可以保持在数百万)。

要求是:如果带有键 XYZ 的对象是从网络到达的,并且队列已经有带有键 XYZ 的对象,那么我需要重写该对象,并且该对象在队列中的位置应该保持不变。例如,如果一个值为 25 的键“Oracle”的对象是从网络到达的,并且一个键为“Oracle”且值为 10 的对象已经存在于队列中的位置 120,那么我需要用值 25 覆盖值 10并且位置应保持 120。

我尝试使用线程安全队列和设置来实现这一点,当来自网络的对象到达时,我首先检查键是否存在于集合中,如果键不存在我在集合中添加键并在队列中添加对象。如果存在键,那么我对队列中的键执行线性搜索并覆盖对象。

如果我对队列中已有的密钥进行非常频繁的更新,性能将会非常缓慢。

有没有有效的方法来实现这个?提前致谢。

【问题讨论】:

  • 您是否有理由不使用std::liststd::vector std::mapstd::unordered_map 来存储您的状态?
  • 这取决于您使用的数据结构和实现。 STL?促进?你自己的实现?
  • @Jason:我正在使用 std::deque 因为我不想在开始时为 std::vector 分配非常高的容量。在我的情况下,如果我不分配大容量的向量,它将非常低效,因为它会重新分配和复制/移动元素,因为没有足够的容量。
  • @Dai:我正在使用 stl、std::deque 和 std::set

标签: c++ performance message-queue


【解决方案1】:

由于队列未排序,因此没有比线性搜索更快地获取数据的真正方法。 您可以使用具有优先级的队列。 std::priority_queue 不允许快速更改优先级,您必须使用 boost。

你也可以试试这个算法:

  • 将 Google、Microsoft、Apple 等密钥存储在 unordered_map 中。 还要记录到目前为止已处理的项目数。
  • 从队列中移除项目时,增加计数并从地图中移除键。
  • 当一个项目到达队列时,
    • 在地图中查找键是否存在(线性时间)
    • 如果是,请更改 queue[index -count] 处的值(线性时间)
    • 如果还没有,请存储 map[key] = count + index where the new item is placed in the queue(线性摊销时间)

我不提供任何保证,我没有测试过这个算法。

【讨论】:

  • 对象需要在 FIFO 中处理。您建议的算法确实帮助我找到了具有恒定时间复杂度的正确解决方案。在 unordered_map 中,键的值需要是元素的序列号,因为队列为空(不是当前索引号),例如如果将 {"Google", 100}, {"Apple", 200} 和 {"YouTube", 300} 添加到队列中,则序列号达到 2(从 0 开始),假设从队列中删除 2 个元素现在添加了 {"XYZ", 400},“XYZ”应该在地图中具有序列号 3,即使它的当前索引在队列中是 1。非常感谢..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多