使用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);
};
是否可以使用std::vector
而不会失去太多性能?
编辑:
我找到了一种用std::vector
替换原始C缓冲区的方法。
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()
次调用。但我认为惩罚是微不足道的。
感谢任何更好的方式。
答案 0 :(得分:1)
从C ++ 11开始,C数组的大部分部分被std::array取代:
std::array<BYTE, MAX_SIZE> buffer;
它只是C数组的一个薄包装器。因此,从性能角度来看,你不会失去任何东西。然而,有更好的工作。
但是和C数组一样,它们只适用于编译时已知大小的固定时间数组。无法调整它们的大小。但是如果我正确地阅读了你的问题,你就不需要那么多的灵活性了。
答案 1 :(得分:1)
通过TCP连接接收消息时,缓冲区中的最后一条消息可能不完整。处理完完整的消息后,人们通常只会memmove
将最后一条未完成的消息发送到缓冲区的开头。
另一种策略是使用“智能”环形缓冲区来避免memmove
,并且还避免数据在环形缓冲区上回绕,从而造成不连续性。要创建“智能”环形缓冲区,请使用mmap
为缓冲区分配内存,并两次映射页面的相同区域,并且两次之间没有间隙。这种从缓冲区末尾读取数据的方式将从头开始继续读取,从而避免了使用常规环形缓冲区时固有的不连续性。
为网络缓冲区使用std::vector
不太理想,因为调整向量的大小会初始化其元素,这些元素随后会被recv
调用覆盖。此类缓冲区不需要初始化。
答案 2 :(得分:0)
如果你想要类似于C的行为(也就是说,你想保证向量不会自由或为底层向量分配更多内存),一个很好的解决方案是使用Boost's static_vector。它静态地分配底层缓冲区,但否则它就像一个普通的向量。
boost::static_vector<BYTE, MAX_SIZE> buffer;
但是,对于此类活动,您还可以查看std::queue或boost::cirular_buffer,看看其中一项是否符合您的需求。
答案 3 :(得分:0)
完全可以用std::vector
或等效地std::array
替换它。您不需要调整矢量的大小,因此也不需要。
std::vector<BYTE> buffer(MAX_SIZE);
BYTE * start = buffer.data();
int dataSize = 0;
while (appRunning())
{
dataSize += Receive(start, MAX_SIZE - dataSize);
int processedSize = ProcessBuffer(buffer.data(), dataSize);
ASSERT(processedSize <= dataSize);
dataSize -= processedSize;
start = std::copy_n(buffer.data() + processedSize, dataSize, buffer.data());
};
答案 4 :(得分:-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);
};