Boost序列化和文件IO非常慢

Boost serialization and file IO is extremely slow

本文关键字:非常 IO 文件 序列化 Boost      更新时间:2023-10-16

我正在制作一个游戏,并有一个用于加载三维模型的资源文件格式,其中纹理和网格等定义如下:

/* 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从文件系统中保存/加载,到目前为止,这个文件系统非常棒,因为它几乎不需要任何代码

然而,在导入一些三维模型,然后尝试再次加载后,加载时间是巨大的;从文件系统加载然后反序列化几乎需要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/

我使用的资源文件在光盘上大约是26MB,包含3个包模型和14个包纹理。我该怎么办呢?我的文件格式设计是一条死胡同吗?

这对于26MB来说时间太长了。我看到你在VS2012中运行它。我建议您在版本中尝试并在VS2012环境之外运行该程序,只需直接从文件资源管理器中单击.exe即可。

此外,您不需要在内存中加载整个文件来反序列化其内容。

您可以尝试使用以下代码:

std::ifstream file("path.dat");
boost::archive::binary_iarchive iar(file);