2016-05-11 3 views
1

Я пытаюсь найти самый быстрый способ сохранить постоянное количество элементов в векторе (или, может быть, есть какая-то готовая структура, которая делает это автоматически).Сохранение постоянного количества элементов в векторе

В моем приложении я добавляю несколько элементов в вектор, и мне нужно сделать это быстро. Из-за изменения размера вектора в какой-то момент он значительно уменьшает общую скорость приложения. То, что я думал о том, чтобы сделать что-то вроде этого:

if(my_vector.size() < 300) 
    my_vector.push_back(new_element); 
else 
{ 
    my_vector.pop_front(); 
    my_vector.push_back(new_element); 
} 

, но после первых тестов я понял, что это может быть не лучшим решением, потому что я не уверен, что если pop_front() и позже push_back() не по-прежнему необходимо изменить размер в какой-то момент.

Есть ли другие решения для этого?

+0

IIRC он изменяет размер, когда счетчик переходит на мощность 2. – Carlos

+3

Вы можете использовать 'std :: array', если знаете размер элементов, которые вы хотите. Или даже лучше использовать и 'std :: deque', который оптимизирован для вставки/удаления передних/задних и всегда проверяет' size() 'перед тем, что вы делаете. – GeorgeAl

+0

@ Карлос Потому что в моем случае у меня есть 100 с этих векторов, даже если половина изменяет размер, это занимает значительное количество времени. – sebap123

ответ

1

Для реализации фиксированного размера контейнера с push_back и pop_front и минимальной перетасовки памяти, используйте std::array из соответствующих размер. Чтобы отслеживать вещи, вам понадобится передний индекс для нажатия элементов и индекс назад для появления вещей. Чтобы нажать, сохраните элемент в месте, заданном front_index, затем увеличьте front_index и возьмите остаток по модулю размера контейнера. Чтобы постить, прочитайте элемент по адресу, указанному back_index, и настройте этот индекс так же, как вы сделали front_index. При этом код в вопросе будет делать то, что вам нужно.

+0

Ваша идея действительно имеет смысл. Спасибо. – sebap123

2

Использовать std::queue. Его базовый контейнер - std::deque, но, как стек, интерфейс очереди предназначен специально для операций FIFO (push_back, pop_front), что именно то, что вы делаете в своей ситуации. Вот почему для этого лучше подходит deque:

Хранение детекса автоматически расширяется и сжимается как . Расширение deque дешевле расширения std :: vector, поскольку оно не связано с копированием существующих элементов в новое место памяти.

Сложность (эффективность) общих операций на двусторонних очередей как следующим образом:

  • Random Access - постоянная О (1)
  • вставки или удаления элементов в конце или начале - постоянная O (1)
+0

Следует подчеркнуть, что 'pop_front' - очень медленная операция в' vector'. Нам нужна структура с хорошей производительностью 'pop_front()'. –

0

Вам просто нужно reserve емкость до разумного числа. Вектор автоматически не будет shrink. Таким образом, он будет расти и, возможно, остановиться в какой-то момент.

Вы также можете быть заинтересованы в политике изменения размера. Например Facebook сделало серьезные исследования и создал собственную реализацию вектора - folly::fbvector, который имеет лучшую производительность, чем std::vector

Смежные вопросы