我正在尝试为新项目选择合适的数据类型以满足以下要求:
离。让我们说1,2,3,4,5,6插入容器中。一段时间后6将被删除,7将被插入,所以列表将是7,1,2,3,4,5然后5将被删除等...但大小必须相同。
我想知道从性能和内存的角度来看,哪种数据结构最适合我的数据结构。
...谢谢
编辑:顺便说一下它与基本的FIFO逻辑有点不同,因为我们创建10个元素(大小)数据容器,但只插入3个元素,即使它没有到达容器的末尾(大小限制) ),如果指定的时间过去,它将被删除。
顺便说一句,我正在考虑使用boost:array,但对std:vector和std:deque有点困惑。这种情况有什么特别的优势吗?
答案 0 :(得分:6)
你需要的是在固定大小的数组上构建的循环缓冲区,这是非常简单和最快的数据结构。
您可以编写自己的循环缓冲类或尝试使用循环缓冲区http://www.boost.org/doc/libs/1_54_0/libs/circular_buffer/doc/circular_buffer.html
的boost实现答案 1 :(得分:1)
看起来你需要一个queue,可能是由支持FIFO的一些优化的固定大小容器备份的。
答案 2 :(得分:0)
我们都知道,从我们的数据结构和算法类中,插入和删除的位置很可能我们应该使用某种链接列表。可能我们所知道的是错误的。
现代内存快速复制大量数据(因此您不必担心复制数据),并使用缓存进行线性搜索(链表结构将有效失败)。结合这两个因素可能意味着你应该使用一个好的旧向量或boost :: array。
答案 3 :(得分:0)
你需要std :: vector支持std :: vector并且具有一些固定容量:
std::vector<YourType> underlying_storage(capacity);
std::queue<YourType, std::vector<YourType>> queue(std::move(underlying_storage));
// Now your queue is backed up by vector with predefined capacity
答案 4 :(得分:0)
对此最快的解决方案是静态分配的数组,您可以使用head / tail / count自己处理队列;例如
#define MAX_NUMBER_OF_ELEMENTS 10
// Use statically-allocated memory
unsigned char raw_buf[MAX_NUMBER_OF_ELEMENTS * sizeof(X)];
X * const buf = (X *)&raw_buf[0];
int head, tail, count;
// Returns the address for a new element on the queue
inline void *add_element_address() {
void *p = &buf[head];
if (++head == MAX_NUMBER_OF_ELEMENTS) head = 0;
count++;
return p;
}
// Removes oldest element from the queue
inline void remove_element() {
buf[tail].~X();
if (++tail == MAX_NUMBER_OF_ELEMENTS) tail = 0;
count--;
}
// Get the n-th element from the queue where 0 is the
// last added element and count-1 is the oldest one.
X& element(int index) {
index = head - index - 1;
if (index < 0) index += MAX_NUMBER_OF_ELEMENTS;
return buf[index];
}
void add_element(... constructor arguments ...) {
new (add_element_address()) X(... constructor arguments ...);
}
使用这种方法,缓冲区将位于内存中的固定地址(因此也释放寄存器),并且对象上不需要任何类型的副本(它们使用placement new直接构建)。添加,删除和索引访问操作都是O(1)
。