2016-09-23 7 views
-2

Итак, моя цель - захватить данные в буфере. Мне нужна скорость, и мне нужен только фиксированный размер, поэтому я думал, что круговой массив будет лучшим.взять массив из круглой матрицы

Но то, что я хочу сделать, это на каждом шагу к:

  • первый, перезаписать самую последнюю информацию в массиве с новейшим, который только что прибыл
  • дальше, используя весь массив, начиная с самых старых до последней
  • повторе

мне трудно увидеть, как обрабатывать второй шаг в C++, будучи эффективным. Или может быть, что-то еще, чем круговой массив, было бы лучше? Любые рекомендации или точки зрения приветствуются.

Чтобы иметь что-то более графический:

for step in steps: 
    (current writing position = 2) 
    current buffer = [8, 9, 3, 4, 5, 6, 7] 

    new info = 10 

    overwrite buffer(new info) 
    new buffer = [8, 9, 10, 4, 5, 6, 7] 

    current writing position += 1 //(3) 

    array to use = [4, 5, 6, 7, 8, 9, 10] 

    function(array to use) 

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

То, что я имею в виду, чтобы скопировать последнюю часть и первую часть, а затем объединить их:

std::vector<int> buffer{8, 9, 10, 4, 5, 6, 7}; 

std::vector<int> oldest(&buffer[3],&buffer[6]); 
std::vector<int> youngest(&buffer[0],&buffer[2]); 

oldest.insert(oldest.end(), youngest.begin(), youngest.end()); 

function(oldest) 

Если вы знаете что-то, что было бы быстрее, сообщите мне.

+0

Если кто-то подумает, что для понимания моей проблемы лучше изменить псевдокод с помощью C++, дайте мне знать. Я изменю его. Мой текущий код более сложный. – user1854186

ответ

1

Если вам действительно нужна скорость, вам не следует копировать элементы, но используйте информацию индекса, которую вы уже имеете, чтобы получить доступ к элементам в правильном порядке.

Таким образом, для функции обработки потребуется просто указатель на массив (или ссылка на std :: vector), знать размер и текущую рабочую позицию.

// process from working pos to end of buffer 
for(int i = current_pos; i < buffer_size; ++i) { 
    processElement(new_buffer [i]); 
} 
// process the remainder from begin to working pos 
for(int i = 0; i < curent_pos; ++i) { 
    processElement(new_buffer [i]); 
} 

Это не должно быть трудно inplement как ваше рабочее положение отмечает и, в начале и в конце данных для обработки.

+0

Дело в том, что я использую стороннюю библиотеку, а ее функции нужен весь массив. Я не могу просто обработать один элемент буфера. – user1854186

+0

Какой тип массива выполняет функция? Откуда он получает информацию о размере? Смысл, как функция знает, сколько элементов обрабатывать? – Aaron

+0

Является ли использование памяти проблемой? Если нет, есть простой способ снизить затраты на копирование. – Aaron

0

Этот подход уменьшает накладные расходы n-fold, где n - количество дополнительных элементов массива + 1.

Пример: массив с 2 дополнительными элементами

Обратите внимание, что в этом случае, самое старое значение на левой стороне, функция была вызвана с указателем на обр [0] (start_pos = 0)

arr == [3, 4, 5, 6, 7, 8, 9, x, x] 

теперь позволяет вставить на новое значение 10

arr == [3, 4, 5, 6, 7, 8, 9, 10, x] 

start_pos += 1 

вызов функции с указателем на второй элемент (старый 3 не будет использоваться)

function(arr + start_pos) 

и теперь добавить 11 и увеличивать рабочее положение (старый 4 не будет использоваться)

arr == [3, 4, 5, 6, 7, 8, 9, 10, 11] 

start_pos += 1 

function(arr + start_pos) 

Теперь массив заполнен.

И только теперь необходимо скопировать последние элементы в начало массива (после начала start_pos до конца) и установить working_pos на 0 в зависимости от количества дополнительных элементов, которые необходимо выполнить только каждый 10-й, 100-й или даже 1000-й итерации!

результат копирования будет:

arr == [6, 7, 8, 9, 10, 11, 9, 10, 11] 
          * 
start_pos = -1 // prepare for the +1 in regular iteration. 

рядом добавленную стоимость (12) перезаписывает значение *

arr == [6, 7, 8, 9, 10, 11, 12, 10, 11] 

start_pos += 1 // is 0 now 

function(arr + start_pos) 

Конечно, вам нужно одну переменную, чтобы определить поз, чтобы вставить новый элемент за другим значением val или вы получаете из start_pos + nElemsToProcess

Если ваша функция() принимает только контейнеры std, это, вероятно, не самый правильный выбор для удовлетворения потребности в sp ПЕД.

+0

Спасибо! Интересно видеть другую точку зрения :) Но с таким подходом нам еще нужно скопировать в какой-то момент? У вас есть идея, когда стоит сравнить с круговым буфером, где нет необходимости копировать? Btw это то, что вы назвали экстренной копией? (никогда не слышал об этом раньше) – user1854186

+0

Я имел в виду, что стоимость чрезвычайно снижена по сравнению с копированием всего в новый массив, потому что вы можете напрямую обращаться ко всем элементам строки ** без необходимости обертывания **, поскольку вам нужно будет с круговой). Проблема в том, как Tensor берет данные (всегда копируя!?). – Aaron

+0

Кажется, так:/ Я пока не нашел способ сделать это по-другому. Сначала я попробую сначала вы первый подход. Я скопирую элемент на элемент в тензоре. – user1854186

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