迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > C++ >

C++ 中的序列化库

作者:迹忆客 最近更新:2023/08/25 浏览次数:

在本文中,您将了解不同的 C++ 序列化库。

首先,我们将了解序列化及其在 C++ 中的用途。 接下来,我们将讨论 C++ 中的序列化库以及如何在我们的程序中使用它们。


序列化概述

程序员经常使用内存中的数据对象。 有时,对象必须通过网络发送或写入持久存储(通常是文件)以保存程序状态的某些部分。

序列化是将数据或对象状态转换为二进制格式的过程/技术。 二进制形式是用于存储/保留对象状态或通过计算机网络将其传输到内存、数据库、文件或磁盘的字节流。

序列化过程的逆过程称为反序列化。 当您想要在程序执行期间或之后维护结构化数据(即 C++ 类或结构)的状态时,序列化非常适合。

您可以通过本网站上的示例了解 serialize() 和 deserialize()。

序列化提供了软件对象值的稳定字节表示。 然后,这些字节可以通过网络发送,即使在未来使用不同的硬件和软件的实现中,该网络也将继续正常工作。

各种语言的连载

在继续之前,序列化过程在不同语言中的实现方式有所不同。 下面让我们来探讨一下。

  1. 在Java中,序列化方法是writeObject,它在ObjectOutputStream中实现。
  2. 在Python中,序列化方法是pickle.dumps()。
  3. 在 Ruby 中,序列化方法是 marshal.dump()。
  4. 在C++中,方法是boost::archive::text_oarchive a (filename); 一个<<数据; 调用序列化方法
  5. 在MFC(微软基础类库)中,序列化方法是:从CObject驱动你的类。

我们的主要关注点是 C++ 序列化,所以让我们看看它是如何工作的。

C++ Boost.Serialization 使用文本存档对象。 序列化写入作为输出数据流运行的输出归档对象。

当针对类数据类型调用时,>> 输出运算符调用类来序列化函数。 每个序列化函数都使用 & 运算符,或通过 >> 递归序列化嵌套对象以保存或加载其数据成员。

为了更好地理解 C++ 中的序列化,您可以查看此网站。


C++ 中的序列化库

C++ 提供了许多用于序列化的库(Boost 序列化除外)。 所有库都有助于实现高序列化性能,因此让我们探索其中一些。

Protocol

Protocol Buffers (Protobufs),一种用于序列化数据的跨平台。 它有助于程序之间通过网络进行通信。

Protobuf序列化机制是通过协议应用给出的。 该编译器将解析 .proto 文件,并根据其参数配置的语言(在本例中为 C++)生成源文件作为输出。

您可以阅读此链接上的教程以更好地了解 Protobuf。

FlatBuffers

FlatBuffers 是一个开源跨平台,用于实现最大内存效率。 您可以直接访问序列化数据,无需解析它,具有前向/后向兼容性。

使用 FlatBuffers,首先使用 --CPP 选项生成 C++ 模式。 然后,您可以在文件中包含 Flatbuffer 来读取或写入此生成的代码。

您可以在此链接中找到使用 FlatBuffers 的序列化实现。

Cereal

Cereal 是仅包含头文件的 C++ 11 序列化库。 Cereal 接受任意数据类型,并将它们可逆地转换为不同的表示形式,例如紧凑的二进制编码、XML 或 JSON。

Cereal 是可扩展的、快速的、经过单元测试的,并提供类似 Boost 的熟悉语法。 要下载完整的谷物食品库,请单击此处。

接下来,我们有一个示例来展示谷物库的使用:

#include <cereal/types/unordered_map.hpp>
#include <cereal/types/memory.hpp>
#include <cereal/archives/binary.hpp>
#include <fstream>

struct MyRecord{
  uint8_t x, y;
  float z;
  template <class Archive>
  void serialize( Archive & ar ){
    ar( x, y, z );
  }
};
struct SomeData{
  int32_t id;
  std::shared_ptr<std::unordered_map<uint32_t, MyRecord>> data;
  template <class Archive>
  void save( Archive & ar ) const{
    ar( data );
  }
  template <class Archive>
  void load( Archive & ar ){
    static int32_t idGen = 0;
    id = idGen++;
    ar( data );
  }
};
int main(){
  std::ofstream out("out.cereal", std::ios::binary);
  cereal::BinaryOutputArchive archive( out );
  SomeData myData;
  archive( myData );
  return 0;
}

在主函数中,我们以二进制模式创建一个名为 os.cereal 的二进制文件。

在下面的行中,我们从在谷物库的 archives 文件夹中定义的 binary.hpp 创建 BinaryOutputArchive 类的对象。 我们将文件对象传递给 BinaryOutputArchive 的构造函数。

接下来,我们创建要序列化的数据对象,类一些数据的对象。 最后,在主函数的第四行中,我们将数据对象传递给存档,间接调用 save 函数将数据保存在输出文件中,以将序列化对象保存在输出文件 out.cereal 中。

二进制文件 out.cereal 包含我们的序列化数据。 此代码的输出将是文件 out.cereal 中的数据。

这些数据是二进制形式的,我们可以使用不同操作系统中可用的不同实用程序/命令来检查它。

HPS

HPS 是一种高性能仿真工具,是 C++11 中用于数据序列化的纯头文件库。 HPS 将您的数据编码为压缩格式,以便轻松通过网络传递。

HPS 比 C++ 中的普通 boost 序列化快 150%,因为它只需要一行用于标准模板库和原始数据类型的代码。

您还可以使用 write to_stream 和 from_stream 函数来读取和写入文件中的数据。 为了更好地了解HPS,您还可以访问该网站。

GitHub 消息包

MessagePack 是一种特定于开源的序列化格式。 您可以轻松地交换 JSON 和 XML 等不同格式的数据。

整数值只需要一个字节来编码数据,而字符串值需要一个额外的字节。

要进一步实现 msgpack,您可以访问该链接。

Boost.Serialization

C++ 中的 Boost Serialization 库可以将对象转换为字节以便保存和加载以恢复它们。 不同的格式生成字节序列。

Boost 支持所有这些格式。 序列化仅适用于该库。

在 C++ 中,要序列化的每个对象都需要实现序列化方法。 它应该以档案作为参数; 档案类似于输入/输出数据流。

您可以使用通用运算符并处理机器人保存和加载操作,而不是使用运算符 << 或 >>。 您可以在此网站上阅读有关 boost 序列化的信息。

Apache Avro

Apache Avro 是一个数据序列化系统。 Avro C++ 是一个实现 Avro 规范的 C++ 库,该库旨在用于流管道。

例如,Apache Kafka 使用集中管理的模式执行数据序列化和反序列化。

Avro 不需要代码生成; 您可以使用代码生成工具。 代码生成器读取模式并输出一个 C++ 对象来表示 .schema 中模式的数据。

它还创建代码来序列化该对象并反序列化它。 在这里,所有繁重的编码工作都已为您完成。

即使您希望使用核心 C++ 库编写自定义序列化器或解析器,生成的代码也可以作为如何使用这些库的示例。

这种风格可以工作,但您可以使结构或类可序列化以获得完美的解决方案。

Cap’n Proto

Cap’n Proto 可以轻松地互换数据格式,因为其功能依赖于 RPC(远程过程调用)系统。 Cap'n Proto 中没有编码/解码的概念。

数据交换格式充当编码并代表内存。 您可以通过构建数据轻松地直接从磁盘写入字节。

您可以在 Cap’n Proto 页面上找到最好的示例。

Thrift

Apache Thrift 是一个专注于语言问题的序列化框架。 您可以在 IDL(接口定义语言)中定义抽象数据类型,这将进一步编译为任何支持的语言的源代码。

然后,这些生成的代码将为用户定义类型提供完整的序列化。 Apache Thrift 确保任何数据类型都可以用它读取或写入。

您可以在此页面上找到 Apache Thrift 的最佳示例。

YAS

YAS 是作为 Boost.serialization 的替代品而创建的,因为它的序列化速度较低; 它也是一个仅包含头文件的文件,不需要任何第三方库。 它支持二进制、测试和 JSON 格式,并且需要 C++11。


所有序列化库之间的比较

所有这些库都提供序列化,并且在不同时期都有它们的序列化。 我们只是向您展示这些库的结果,而您可以在此页面上找到代码和更多详细信息(同一行已在上一行中共享)。

在本文中,我们展示了从一篇文章中获取的结果。

该代码已在运行 Ubuntu 16.04 的具有 Intel Core i7 处理器的典型台式计算机上运行,并计算了它们的平均时间。

序列化器 对象的大小 平均总时间
thrift-binary 17017 1190.22
thrift-compact 13378 3474.32
protobuf 16116 2312.78
boost 17470 1195.04
msgpack 13402 2560.6
cereal 17416 1052.46
avro 16384 4488.18
yas 17416 302.7
yas-compact 13321 2063.34

Cap’n Proto 和 Flatbuffers 以序列化形式存储数据,其中序列化意味着获取指向内部存储的指针。 因此,在 Cap’n Proto 中,我们测量整个构建/序列化/反序列化周期。

对于其他库,我们还可以对已构建的数据结构进行循环序列化/反序列化。

序列化器 对象的平均大小 总时间
CAPnproto 17768 400.98
flatbuffers 17632 491.5

如果你根据大小看到上面的数据表示,YAS 比其他库占用更多的对象大小。 尽管如此,如果考虑序列化时间,YAS 花费的时间仍然很短。

因此,YAS 显示了所有库中最快的序列化。

我们希望您现在了解序列化及其用途。 现在,您知道哪些库可以在 C++ 中进行序列化,或者哪个库可以实现最快。

上一篇:C++ 中的 time(NULL) 函数

下一篇:没有了

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

C++ 中的 time(NULL) 函数

发布时间:2023/08/24 浏览次数:162 分类:C++

本文将讨论 C++ 中的 time(NULL) 函数。C++ 中的 time(NULL) 函数 time() 函数,参数为 NULL,time(NULL),

C++类函数声明中的const关键字

发布时间:2023/08/24 浏览次数:136 分类:C++

在C++中,const关键字定义了那些在程序执行期间不会改变并保持不变的值。 对于变量及其保存的数据来说,这听起来非常简单。

C++ 中的 shellExecute() 函数

发布时间:2023/08/24 浏览次数:60 分类:C++

这个小型编程教程将讨论 C++ 中的 ShellExecute() 库函数。 该库函数主要用于通过C++程序打开或执行任何文件(例如脚本文件)。C++ 中的 ShellExecute() 函数

C++ 中默认参数的重新定义

发布时间:2023/08/24 浏览次数:170 分类:C++

在本文中,您将学习如何处理 C++ 中默认参数错误的重新定义。 C++ 中的默认参数必须在方法或函数的声明或定义中指定,但不能同时指定,因为存在重复。

C++ 形式参数的重新定义

发布时间:2023/08/24 浏览次数:133 分类:C++

在本文中,我们将讨论 C++ 中形式参数的重新定义问题。首先,我们将讨论函数定义和形式参数。 接下来,我们将讨论形式参数的重新定义问题。

C++ 工厂方法

发布时间:2023/08/24 浏览次数:78 分类:C++

工厂方法是 C++ 中的一种对象创建设计模式,用于创建对象同时隐藏其组合,以便用户可以使用接口而无需看到任何方法调用。C++ 中的工厂方法 工厂是虚拟构造函数,允许程序员设计让用户与

C++ 调用父方法

发布时间:2023/08/24 浏览次数:132 分类:C++

本文将简要讨论如何在 C++ 中从派生类函数调用父类函数。在C++中调用父类函数 在C++中调用函数就是将控制权转移给函数。

C++ 中的逆矩阵

发布时间:2023/08/24 浏览次数:96 分类:C++

本文将解释矩阵求逆及其使用 C++ 的实现。 为了方便理解C++的实现,我们首先需要理解矩阵逆的概念。矩阵的逆 求矩阵的逆矩阵需要三个步骤。

用 C++ 读取 PPM 文件

发布时间:2023/08/24 浏览次数:108 分类:C++

在本文中,我们将了解 PPM 文件并使用 C++ 读取它们。我们将首先讨论并了解 PPM 文件格式。 稍后,我们将学习用 C++ 读取 PPM 文件的分步过程。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便