现代C 的对象序列化与反序列化魔法
- header-only
- C 20
- 支持STL常用容器
- STL相关的序列化逻辑分离,按需引入减少编译压力
- 支持自定义类对象(侵入式与非侵入式)
- 支持智能指针与原始指针
- 原始指针遵循现代C 实践,不持有对象所有权
- 当前设计仅允许原始指针指向
std::unique_ptr
持有的对象
- 支持
std::optional
,std::tuple
- 字节序无关
- 基于
varint
/zigzag
编码&解码u/i 16/32/64
- 浮点数则在序列化时将其转换为小端序,反序列化时转换为本机字节序,仅支持本机为小端/大端
- 基于
- 可选的版本号控制
-
CPU: Intel(R) Core(TM) i7-8700K CPU @ 3.70GHz 3.70 GHz
-
RAM: 32.0 GB
-
Compiler: MSVC - v1929, /O2
-
ntdll.dll - pdber object
-
RawSize:
417,507 bytes
*4,000 count
=1,670,028,000 bytes
≈1.5 GB
-
IoStream:
sezz::MemoryIoStream
-
ObjectCount:
std::string total integral(bool、uint8_t、size_t) 46,900,000 51,484,000
IoStream Init Buffer Size | Raw Size | Serialized Size | Time |
---|---|---|---|
1,024 bytes |
1,670,028,000 bytes |
1,028,876,000 bytes |
1,557 ms |
1,028,876,000 bytes |
1,670,028,000 bytes |
1,028,876,000 bytes |
1,166 ms |
time: 2,685 ms
- 构造
std::string
时的new
,是反序列化耗时的主要原因之一。
Type | Performance(RawSize) |
---|---|
Serialize.init_small | ≈1,022MB/s |
Serialize.init_large | ≈1,365MB/s |
Deserialize | ≈593MB/s |
鄙视一下cpp-serializers这个项目,yas测试用的自己的MemoryIoStream,cereal用的std::stringstream,实际性能差距都在这里。
#include <iostream>
#include <fstream>
#include <sezz/sezz.hpp>
#include <sezz/stl/string.hpp>
#include <sezz/stl/unordered_map.hpp>
int main() {
std::fstream fs;
fs.open("test.bin", std::ios::binary | std::ios::out | std::ios::in | std::ios::trunc);
sezz::BinaryOutputArchive outar(fs);
std::unordered_map<std::string, std::string> test_map {
{ "pair_key_1", "pair_value_1" },
{ "pair_key_2", "pair_value_2" }
};
outar.Save(test_map);
fs.seekg(0);
sezz::BinaryInputArchive inar(fs);
auto test_map_de = inar.Load<std::unordered_map<std::string, std::string>>();
}
- C 序列化对象
- 计都
- 为此项目的建设提供了许多指导。
- cereal
- 参考了一些设计。
- 如何实现对多个字节的数据序列化 压缩