从与对象大小不一致的连续固定大小缓冲区解析对象的有效方法
Efficient approaches for parsing objects from consecutive fixed size buffers that don't align with object size
我正试图在C++中实现一些目标,其中我有一个API从字节数组中读取对象,而我传入的数组被限制为固定大小。在解析出一个完整的对象后,API知道它完成读取的指针位置(当前字节数组中要读取但未完成的下一个对象的开始)。
然后,我只需要将剩余的字节数组与下一个相同的固定大小数组连接起来,并开始在指针位置读取一个新对象,就好像它是新数组的开始一样。
我是C++的新手,我有以下方法可以工作,但看起来相当麻烦和低效。它需要三个向量和大量的清理、保留和插入。我想知道是否有更高效的替代方案,或者至少同样高效,但代码看起来更简洁?我一直在读像stringstream这样的东西,但它们似乎不需要更少的内存拷贝(可能更多,因为我的API需要传入字节数组)。谢谢
std::vector<char> checkBuffer;
std::vector<char> remainingBuffer;
std::vector<char> readBuffer(READ_BUFFER_SIZE);
//loop while I still have stuff to read from input stream
while (in.good()) {
in.read(readBuffer.data(), READ_BUFFER_SIZE);
//This is the holding buffer for the API to parse object from
checkBuffer.clear();
//concatenate what's remaining in remainingBuffer (initially empty)
//with what's newly read from input inside readBuffer
checkBuffer.reserve(remainingBuffer.size() + readBuffer.size());
checkBuffer.insert(checkBuffer.end(), remainingBuffer.begin(),
remainingBuffer.end());
checkBuffer.insert(checkBuffer.end(), readBuffer.begin(),
readBuffer.end());
//Call API here, and I will also get a pointerPosition back as to
//where I am inside the buffer when finishing reading the object
Object parsedObject = parse(checkBuffer, &pointerPosition)
//Then calculate the size of bytes not read in checkBuffer
int remainingBufSize = CheckBuffer.size() - pointerPosition;
remainingBuffer.clear();
remainingBuffer.reserve(remainingBufSize);
//Then just copy over whatever is remaining in the checkBuffer into
//remainingBuffer and make it be used in next iteration
remainingBuffer.insert(remainingBuffer.end(),
&checkBuffer[pointerPosition],&checkBuffer[checkBuffer.size()]);
}
写入append_chunk_into(in,vect)
。它在vect
的末尾附加一个数据块。它根据需要调整大小。顺便说一句,字符大小的非零内存标准布局结构可能是比char
更好的选择。
附加到末尾:
size_t old_size=vect.size();
vect.resize(vect.size()+new_bytes);
in.read(vect.data()+old_size, new_bytes);
或者读取的api是什么。
要进行解析,请将其输入vect.data()
。当它结束ptr
时,返回的指针。
然后`vect.erase(vect.begin(),vect.begin()+(ptr-vect.data()))删除解析的字节。(只有在解析完缓冲区中的所有内容后才能执行此操作,以节省浪费的mem移动)。
一个矢量。它将重用内存,并且永远不会增长到大于读取大小+最大对象1的大小。所以你可以预先预订。
但实际上,通常大部分时间都是io。因此,将优化的重点放在保持数据流畅上。
如果我处于您的位置,我将只保留readBuffer。我会预订READ_BUFFER_SIZE +sizeof(LargestMessage)
。解析后,您将返回一个指针,指向api能够在向量中读取的最后一个内容。然后,我会将结束迭代器转换为指针&*readbuffer.end()
,并使用它来绑定我们必须复制到向量头的数据。一旦你在向量的头上有了这些数据,你就可以使用相同的数据调用读取剩下的数据,除非你加上剩余的字节数。确实需要某种方法来确定剩余数组中有多少字符,但这不应该是无法克服的。
- 在函数内创建的对象的范围 - 如果在函数外部存储和访问引用,它们是否有效?
- C++,在对象内分配多个数据时,堆栈分配是否更有效? 在下面的程序中,类A_Heap的效率会更低吗?
- 在 c++ 中将对象设置为等于同一类的构造函数是否有效?
- 当表示为对象的一维向量时,有效地旋转 NxM 矩阵 (C++)
- 返回一个引用C++中另一个类对象的对象的有效方法
- 在递归函数中更有效地创建对象和对象数组?C++
- 自定义类型转换运算符在转发引用上调用时不起作用(当对象按值传递时有效)
- 有效地分配堆栈对象(由函数的值返回)到堆?
- 如果一个对象是在本地创建的,并在C++中作为异常抛出,那么本地对象如何在其范围之外有效,即在 catch 块中?
- 有没有办法自动初始化 std::shared_ptr 来保存有效对象?
- 如何检查对象有效
- 如何检查指针后面的对象是否有效或已删除?
- 列出 n 个对象的所有 k 排列的有效方法,同时满足特定标准
- 如何使用 stl 容器有效地存储对象?(即根据其字段的值进行搜索)
- 如何有效地初始化大型类的对象
- 与C++共享 Julia 对象的最有效方法是什么?
- 是否有一种有效的方法可以将一系列对象与父/子关系分类
- 什么是将对象相互连接的干净有效的方法
- C++使用 shared_ptr 安全地删除事件对象有效负载
- 在类的构造函数内创建对象有效吗