Boost序列化:如何预测序列化结果的大小? [英] Boost Serialization : How To Predict The Size Of The Serialized Result?

查看:177
本文介绍了Boost序列化:如何预测序列化结果的大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我以这种方式使用booost序列化:

I use booost serialization that way :

Header H(__Magic, SSP_T_REQUEST, 98, 72, 42, Date(), SSP_C_NONE);
Header Z;

std::cout << H << std::endl;
std::cout << std::endl;

char serial_str[4096];

std::memset(serial_str, 0, 4096);

boost::iostreams::basic_array_sink<char> inserter(serial_str, 4096);
boost::iostreams::stream<boost::iostreams::basic_array_sink<char> > s(inserter);
boost::archive::binary_oarchive oa(s);

oa & H;
s.flush();

std::cout << serial_str << std::endl;

boost::iostreams::basic_array_source<char> device(serial_str, 4096);
boost::iostreams::stream<boost::iostreams::basic_array_source<char> > s2(device);
boost::archive::binary_iarchive ia(s2);

ia >> Z;

std::cout << Z << std::endl;

它工作得很好.

尽管如此,我需要在套接字上发送那些数据包.我的问题是,我如何知道另一边需要读取多少个字节?序列化结果的大小不是恒定的,并且btw大于我的结构的sizeof.

Nevertheless, I need to send those packet on a socket. My problem is, how do I know on the other side how many bytes I need to read ? The size of the serialized result is not constant and btw is bigger than sizeof of my struct.

如何确定另一侧的数据完整?我使用循环缓冲区,但要序列化怎么办?

How can I be sure that the data is complete on the other side ? I use circular buffer but with serialisation how to do ?

全力以赴

推荐答案

通常无法预测.这(很大程度上)取决于存档格式.但是,通过对象跟踪,可以完全消除子图,而通过动态类型信息,可以添加很多数据.

In general it's impossible to predict. It depends (a lot) on the archive format. But with object tracking completely subgraphs might be elided, and with dynamic type information a lot of data could be added.

如果您可以为序列化数据提供暂存缓冲区,则可以先序列化为缓冲区,然后再发送大小(现在就知道了),然后再发送有效负载.

If you can afford scratch buffers for serialized data, you can serialize to a buffer first, and then send the size (now that you know it) before sending the payload.

  • 对象跟踪(通过指针/引用进行序列化)
  • 动态多态性(通过(智能)指向基础的指针序列化)
  • 版本控制(除非您针对所涉及的类型将其禁用)
  • 存档头(除非已禁用)
  • 代码转换(除非已禁用)

以下是一些答案,可为您提供有关这些调整点的更多信息:

Here are some answers that give you more information about these tweak points:

  • Boost C++ Serialization overhead
  • Boost Serialization Binary Archive giving incorrect output
  • Boost Serialization of vector<char>
  • Tune things (boost::archive::no_codecvt, boost::archive::no_header, disable tracking etc.)

如果所有数据均为POD,则很容易预测大小.

If all your data is POD, it's easy to predict the size.

如果您在同一台计算机上共享IPC,并且已经在使用循环缓冲区,请考虑将循环缓冲区放入共享内存中.

If you share IPC on the same machine, and you're already using circular buffers, consider putting the circular buffer into shared memory.

我有很多这样的例子(搜索managed_shared_memorymanaged_mapped_file).

I have lots of answers (search for managed_shared_memory or managed_mapped_file) with examples of this.

这里是一个具体的示例,它关注于无锁的单一生产者/单用户场景:

A concrete example, focusing on a lock-free single-producer/single-consumer scenario is here: Shared-memory IPC synchronization (lock-free)

即使您选择/需要流式传输消息(例如通过网络),您仍然可以使用受管理的外部缓冲区.因此,即使不要求所有数据都是POD,也可以避免进行任何序列化. (技巧是在内部使用offset_ptr<>代替原始指针,从而使所有引用都相对.)

Even if you choose to/need to stream messages (e.g. over the network) you can still employ e.g. Managed External Buffers. Hereby you avoid the need to do any serialization even without requiring all data to be POD. (The trick is that internally, offset_ptr<> is used instead of raw pointers, making all references relative).

这篇关于Boost序列化:如何预测序列化结果的大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆