用于固定大小和预定义类型数据的C ++向量,列表或数组

时间:2013-11-05 09:10:35

标签: c++ arrays performance list vector

我正在尝试为新项目选择合适的数据类型以满足以下要求:

  • 高!时间关键(用于输入数据)
  • 对容器中的数据没有随机插入或任何操作(只读和顺序插入)
  • 大小将在编译时固定(因此不需要动态分配)
  • 在某个定义的时间段(通过线程或服务)之后,数据将按顺序删除,并且空白空间必须再次可用于新的数据。

离。让我们说1,2,3,4,5,6插入容器中。一段时间后6将被删除,7将被插入,所以列表将是7,1,2,3,4,5然后5将被删除等...但大小必须相同。

我想知道从性能和内存的角度来看,哪种数据结构最适合我的数据结构。

...谢谢

编辑:顺便说一下它与基本的FIFO逻辑有点不同,因为我们创建10个元素(大小)数据容器,但只插入3个元素,即使它没有到达容器的末尾(大小限制) ),如果指定的时间过去,它将被删除。

顺便说一句,我正在考虑使用boost:array,但对std:vector和std:deque有点困惑。这种情况有什么特别的优势吗?

5 个答案:

答案 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。

但是不要相信我的话,here's Bjarn Stroustrup explaining it all.

答案 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)