我有一个对象定义为:
std::unordered_map<std::string, std::vector<int>> large_obj;
它可以存储非常大量的数据(包含许多行),并且效果非常好。
但是,我想将large_obj
备份到一个文件中,稍后我会再次从文件加载到另一个对象。
读取/写入此对象的最优化方法是什么,而不是在预定义结构中写入文件中的每一行?
请记住:
节省对象I / O的时间?
答案 0 :(得分:1)
您可以尝试Boost::serialization。但请记住,此库具有错误的向后兼容性。序列化后,您只需将所有存档数据写入文件即可。
本机序列化方法是使用流操作符。这就是boost::serilization
在大多数情况下的工作方式。您可以重载班级成员<<
和>>
运算符以编写和阅读文本格式。但最好使用优雅稳定的解决方案。
答案 1 :(得分:1)
我并不真正关心read()
和write()
的开销 - 只需使用缓冲流和可以读写的数据格式,而无需在数据流中来回跳转
您要写出的序列化流应该足够接近您的数据表示,这样您就可以通过简单的副本接管大量数据,但仍然足够抽象以允许从旧版本的数据格式或在具有数据格式的计算机上重建不同的内部陈述。
我通常会定义一个标题,其中包含幻数,数据格式版本和一组捕获计算机特定部分的值。对于你的情况,那将是
struct header {
char magic[4];
uint32_t endianness; // 0x01020304
uint32_t version; // incremented when format changes
// paranoia
uint8_t char_bit; // std::numeric_limits<char>::digits
// sizeofs for all types format is dependent on
uint8_t sizeof_int; // sizeof(int)
};
当读回数据时,您将标题中的值与您期望的值进行比较 - 如果出现不匹配的情况,您可以添加处理此问题的反序列化代码。
对于行,我会使用类似
的编码uint16 string_length;
char string_data[]; // string_length bytes, padding if odd
uint16 vector_length;
int vector_data[]; // vector_length ints
可以有效地保存和恢复。当您的需求发生变化时,只需增加版本号,定义新格式并调整解析器代码以创建新的内存中表示。
答案 2 :(得分:0)
也许,您可以尝试文档数据库。数据库引擎将部分地处理性能。例如MongoDB。
无法使用最优化的方法。您必须考虑权衡并衡量绩效。 Boost.Serialization是一个很好的选择,但您必须有一套明确的要求,并且至少要对最常见的用例进行一些性能测量。