我应该使用哪一个STL容器作为FIFO?

哪个STL容器最适合我的需求? 我基本上有一个10个元素的容器,在这个容器中我不断push_back新元素,同时pop_front最老的元素(大约一百万次)。

我目前正在使用一个std::deque的任务,但想知道如果一个std::list将更有效,因为我不需要重新分配自己(或者我误解std::deque std::vector ?)。 还是有一个更有效的容器,我的需要?

PS我不需要随机访问

既然有无数的答案,你可能会感到困惑,但总结一下:

使用一个std::queue 。 原因很简单:它是一个FIFO结构。 你想要FIFO,你使用一个std::queue

它使你的意图清楚,任何人,甚至你自己。 std::liststd::deque不。 一个列表可以在任何地方插入和删除,这不是FIFO结构所要做的,而且可以从任一端添加和删除,这也是FIFO结构无法做到的。

这就是为什么你应该使用queue

现在,你问了关于performance。 首先,永远记住这个重要的经验法则: 优先代码,性能最后。

其原因很简单:在清洁和优雅之前努力performance的人们几乎总是最后完成。 他们的代码变成了一团糟,因为他们已经放弃了所有的好东西,为的是什么都不做。

通过首先编写好的可读代码,大部分性能问题都将自行解决。 如果后来你发现自己的性能不足,现在很容易在你的漂亮,干净的代码中添加一个分析器,并找出问题出在哪里。

这一切都表示, std::queue只是一个适配器。 它提供了安全的接口,但在内部使用了不同的容器。 你可以select这个底层容器,这样可以有很大的灵活性。

那么,你应该使用哪个底层容器呢? 我们知道std::liststd::deque都提供了必要的函数( push_back()pop_front()front() ),所以我们如何决定呢?

首先,明白分配(和释放)内存通常不是一件快事,因为它涉及到操作系统并要求它做某事。 list必须在每次添加内容时分配内存,并在内存消失时释放内存。

另一方面, deque大块分配。 它将分配的次数less于list 。 把它想象成一个列表,但是每个内存块可以容纳多个节点。 (当然,我build议你真的了解它是如何工作的 。)

所以,只有这样一个deque才能performance得更好,因为它并不像往常那样处理记忆。 事实上,你处理的是大小不等的数据,在第一次通过数据之后可能不需要分配数据,而列表将不断地分配和释放。

要理解的第二件事是caching性能 。 出门到内存很慢,所以当CPU真正需要的时候,通过把一块内存带回到caching中,这个时间是最好的。 因为deque在内存块中分配,访问这个容器中的一个元素很可能会导致CPU将容器的其余部分也带回来。 现在,任何进一步的访问将会很快,因为数据在caching中。

这不同于一次一个分配数据的列表。 这意味着数据可能遍布在内存中,并且caching性能会变差。

所以,考虑到这一点,一个deque应该是一个更好的select。 这就是为什么它是使用queue时的默认容器。 所有人都说,这仍然只是一个(非常)教育的猜测:你将不得不分析这个代码,在一个testing中使用deque在另一个testing中list一个真正的确定。

但请记住:让代码使用干净的界面,然后担心性能。

约翰提出了一个担心,即包装listdeque会导致业绩下降。 再一次,如果不自己分析,我也不能肯定地说,但是编译器会插入queue调用的机会。 也就是说,当你说queue.push() ,它真的只是说queue.container.push_back() ,完全跳过函数调用。

再一次,这只是一个受过教育的猜测,但使用queue不会降低性能,与使用底层容器原始数据相比。 就像我以前说过的那样,使用queue ,因为它干净,易用,安全,如果真的成为问题configuration文件和testing。

退房std ::队列。 它包装一个底层的容器types,默认的容器是std :: deque。

在性能真正重要的地方,请查看Boost循环缓冲区库 。

我不断push_back新元素,而pop_front最老的元素(大约一百万次)。

一百万人在计算方面真的不是很多。 正如其他人所build议的,使用std::queue作为您的第一个解决scheme。 在不太可能发生的情况下,使用探查器识别瓶颈(不要猜测!),并使用具有相同接口的不同容器重新实现。

为什么不std::queue ? 它只有push_backpop_front

一个队列可能是一个比deque更简单的接口,但是对于这样一个小列表来说,性能的差别可能是微不足道的。

列表也一样 。 只需要select你想要的API。