我正在制作一个游戏并且有一个资源文件格式来加载 3d 模型,纹理和网格等定义如下:
/* PackageHeader definition */
struct PackageHeader
{
std::string mSignature;
uint8_t mMajorVersion;
uint8_t mMinorVersion;
PackageHeader();
};
/* PackageMesh definition */
struct PackageMesh
{
std::vector<Vec3> mVertexData;
std::vector<Vec3> mNormalData;
std::vector<Vec2> mTexCoordsData;
std::vector<uint32_t> mIndiceData;
uint16_t mMaterialIndex;
bool mHasMaterial;
PackageMesh();
};
/* PackageTexture definition */
struct PackageTexture
{
std::string mName;
std::vector<uint8_t> mTextureData;
uint32_t mTextureWidth; // width/height in pixels
uint32_t mTextureHeight;
ITexture::TextureFormat mTextureFormat;
ITexture::TextureType mTextureType;
PackageTexture();
};
/* PackageMaterial definition */
struct PackageMaterial
{
std::string mName;
PackageTexture mDiffuseTexture;
Vec3 mDiffuseColor;
Vec3 mAmbientColor;
Vec3 mSpecularColor;
Vec3 mEmissiveColor;
PackageMaterial();
};
/* PackageModel definition */
struct PackageModel
{
std::string mName;
std::vector<PackageModel> mChildren;
std::vector<PackageMesh> mMeshes;
Mat4 mTransform;
PackageModel();
};
/* JonsPackage definition */
struct JonsPackage
{
PackageHeader mHeader;
std::vector<PackageModel> mModels;
std::vector<PackageMaterial> mMaterials;
JonsPackage();
};
我正在使用 Boost Serialization 从文件系统保存/加载,直到现在这一直非常棒,因为它几乎不需要代码来完成。
但是在导入一些 3d 模型然后尝试再次加载它之后,加载时间非常长;从文件系统加载然后反序列化需要将近 30 秒。
这是序列化/反序列化的代码:
JonsPackagePtr ReadJonsPkg(const std::string& jonsPkgName)
{
std::ifstream jonsPkgStream(jonsPkgName.c_str(), std::ios::in | std::ios::binary); // TODO: support opening of older resource packages
JonsPackagePtr pkg(HeapAllocator::GetDefaultHeapAllocator().AllocateObject<JonsPackage>(), boost::bind(&HeapAllocator::DeallocateObject<JonsPackage>, &HeapAllocator::GetDefaultHeapAllocator(), _1));
if (jonsPkgStream && jonsPkgStream.good() && jonsPkgStream.is_open())
{
std::stringstream buf(std::ios_base::binary | std::ios_base::in | std::ios_base::out);
buf << jonsPkgStream.rdbuf();
buf.seekg(0);
jonsPkgStream.close();
boost::archive::binary_iarchive iar(buf);
iar >> (*pkg.get());
}
jonsPkgStream.close();
return pkg;
}
bool WriteJonsPkg(const std::string& jonsPkgName, const JonsPackagePtr pkg)
{
std::ofstream outStream(jonsPkgName.c_str(), std::ios::out | std::ios::binary | std::ios::trunc);
bool ret = false;
if (outStream.is_open())
{
boost::archive::binary_oarchive oar(outStream);
oar << (*pkg.get());
ret = true;
}
return ret;
}
这是 VS2012 性能分析的图像: http://postimg.org/image/smdsnu5gl/
我正在使用的资源文件在光盘上大约有 26 MB,包含 3 个包模型和 14 个包纹理。我能做些什么,我的文件格式设计是死胡同吗?
最佳答案
对于只有 26MB 的空间来说,时间太多了。我看到你在 VS2012 中运行它。我建议您尝试发布并在 VS2012 环境之外运行该程序,只需直接从文件资源管理器中单击您的 .exe。
此外,您不需要将整个文件加载到内存中来反序列化其内容。
你可以试试下面的代码:
std::ifstream file("path.dat");
boost::archive::binary_iarchive iar(file);
关于c++ - Boost 序列化和文件 IO 非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17329190/