2015-06-19 2 views
4

С буфером C, я часто делаю так:Как эффективно обрабатывать std :: vector, как буфер C?

BYTE buffer[MAX_SIZE]; 
int dataSize = 0; 

while (appRunning()) 
{ 
    dataSize += Receive(buffer + dataSize, MAX_SIZE - dataSize); 

    int processedSize = ProcessBuffer(buffer, dataSize); 
    ASSERT(processedSize <= dataSize); 
    dataSize -= processedSize; 
    memmove(buffer, buffer + processedSize, dataSize); 
}; 

Можно ли сделать это с станд :: вектор без значительной потери производительности?

EDIT: Я нашел способ заменить необработанный буфер C на std :: vector.

std::vector<BYTE> vbuf; 
vbuf.reserve(MAX_SIZE); // allocated at once 

while (appRunning()) 
{ 
    int pendingSize = GetPendingDataSize(); // from a socket 
    if (pendingSize > vbuf.capacity()) 
     pendingSize = vbuf.capacity(); 

    vbuf.resize(pendingSize); 
    int recvSize = Receive(vbuf.data(), vbuf.size()); 
    ASSERT(recvSize < vbuf.size()); 
    int processedSize = ProcessBuffer(vbuf.data(), vbuf.size()); 
    std::rotate(vbuf.begin(), vbuf.begin() + processedSize, vbuf.end()); 
    vbuf.resize(vbuf.size() - processedSize); 
}; 

Фактически, в моем практическом использовании получение данных и обработка данных могут выполняться в многопоточном режиме. Поэтому, используя вектор, мне не нужно вручную управлять распределением буфера, размером данных и объемом буфера. Сравнивая с буфером C, ограничение производительности здесь происходит при вызове vbuf.resize(). Но я считаю, что штраф ничтожен. Любой лучший способ оценивается.

+2

'buffer' является фиксированным. Лучше использовать 'std :: array <>'. – ikh

+1

До тех пор, пока вы не измените размер (std :: vector), вы не потеряете производительность ... Вы можете получить указатель на необработанные данные с помощью std :: vector :: data. Как отметил Иш, вы можете использовать данные std :: array и std :: array ::. std :: array - это контейнер, который инкапсулирует массивы фиксированного размера (в основном «c-массив»). – degski

+0

@ degski. Цель, которую я хочу переместить std :: vector, заключается в том, чтобы избежать ручного управления распределением буфера, размером буфера и размером данных. –

ответ

-1

Запись из памяти, пожалуйста, проверьте, работает ли он для вас:

std::vector<BYTE> buffer; 
buffer.reserve(MAX_SIZE); 
int dataSize = 0; 

while (appRunning()) 
{ 
    dataSize += Receive(&buffer[0] + dataSize, MAX_SIZE - dataSize); 

    int processedSize = ProcessBuffer(&buffer[0], dataSize); 
    ASSERT(processedSize <= dataSize); 
    dataSize -= processedSize; 
    memmove(&buffer[0], &buffer[0] + processedSize, dataSize); 
}; 
+1

Должен быть 'buffer.resize (MAX_SIZE);'. (или просто используйте конструктор 'std :: vector buffer (MAX_SIZE);' – ikh

+0

@lgromanowski. Ваше решение прекрасное, но buffer.size() не представляет текущий размер данных буфера, который полезен в случае приема данных и обрабатывающие данные асинхронны. –

+0

@VietHa Вместо этого мы можем использовать 'dataSize'. Это не такой хороший дизайн, но это не так уж плохо - в случае перехода с C. – ikh

0

Если вы хотите поведение, аналогичное C (то есть, вы хотите, чтобы гарантировать вектор не будет когда-либо бесплатно или выделить больше памяти для основной вектор), хорошим решением является использование Boost's static_vector. Он статически распределяет базовый буфер, но в противном случае он действует как обычный вектор.

boost::static_vector<BYTE, MAX_SIZE> buffer; 

Для этого вида деятельности, однако, вы можете также посмотреть в std::queue или boost::cirular_buffer и посмотреть, если один из них соответствует вашим потребностям.

0

Поскольку C++ 11, C массивы были для большей части заменены std::array:

std::array<BYTE, MAX_SIZE> buffer; 

Это лишь тонкая оболочка вокруг массивов C. Итак, с точки зрения производительности вы ничего не теряете. Однако лучше работать с ними.

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

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