我使用boost :: serialization来保存包含这些数据的对象:
struct Container
{
struct SmallObject
{
struct CustomData
{
unsigned first;
float second;
};
std::vector<CustomData> customData; // <- i can have 1 to 4 of these in the std::vector
float data1[3];
float data2[3];
float data3[2];
float data4[4];
};
std::vector<SmallObject> mySmallerObjects; // <- i can have 8000 to 13000 of the std::vector
};
序列化代码如下所示(在侵入版本中,为了便于阅读,我没有编写上面的函数声明):
template<class Archive> void Container::SmallObject::CustomData::serialize(Archive& ar, unsigned /*version*/)
{
ar & first;
ar & second;
}
template<class Archive> void Container::SmallObject::serialize(Archive& ar, unsigned /*version*/)
{
ar & customData;
ar & data1
ar & data2;
ar & data3;
ar & data4;
}
template<class Archive> void Container::serialize(Archive& ar, unsigned /*version*/)
{
ar & mySmallerObjects;
}
我使用binary_archives。在发布模式下,加载我的容器(带有12000个小对象)大约需要400毫秒。我被告知这太长了。是否有任何设置或不同的内存布局可以加快加载过程?我应该放弃使用boost :: serialization?
答案 0 :(得分:3)
如果我不得不选择Boost.Serialization的最大缺点,那就是性能不佳。如果400ms真的太慢,要么获得更快的硬件,要么切换到不同的序列化库。
也就是说,如果您正在做一些公然“错误”的事情,您应该发布Container
,Container::SmallObject
和Container::SmallObject::CustomData
的序列化代码。您还应该确保它实际上是反序列化需要400毫秒,而不是反序列化+从磁盘读取数据的组合;即,将数据加载到某种内存流中并从中反序列化,而不是从std::fstream
反序列化。
编辑(回应评论):
此代码适用于我使用VC ++ 2010 SP1和Boost 1.47 beta:
double loadArchive(std::string const& archiveFileName, Container& data)
{
std::ifstream fileStream(
archiveFileName.c_str(),
std::ios_base::binary | std::ios_base::in
);
std::stringstream buf(
std::ios_base::binary | std::ios_base::in | std::ios_base::out
);
buf << fileStream.rdbuf();
fileStream.close();
StartCounter();
boost::archive::binary_iarchive(buf) >> data;
return GetCounter();
}
如果这对您不起作用,它必须特定于您正在使用的编译器和/或Boost版本(这是什么?)。
在我的机器上,对于x86发布版本(启用链接时代码生成),从磁盘加载数据大约是反序列化1.28MB文件所需总时间的9%(1 Container
包含13000个SmallObject
个实例,每个实例包含4个CustomData
个实例);对于x64发布版本,从磁盘加载数据大约是反序列化1.53MB文件所花费的总时间的17%(相同的对象数)。
答案 1 :(得分:1)
我建议将项目数写入序列化流,然后使用std :: vector :: reserve分配所需的所有内存。这样,您将进行最少的分配。