【易客吧】_全网激活码总代_激活码商城

您现在的位置是:首页 > 热门资讯 > 正文

热门资讯

Protobuf 的高性能二进制序列化库:protostuff (protobuf序列化和反序列化)

用户投稿2024-04-11热门资讯26

简介

Protostuff 是一个轻量级的 Java 库,用于高效地对 Protobuf 消息进行二进制序列化和反序列化。它提供了比标准 Protobuf 实现更高的性能,而不需要牺牲兼容性或功能。

优点

Protostuff 的主要优点包括:高性能: Protostuff 采用高效的二进制编码,比标准 Protobuf 实现快几个数量级。可扩展性: Protostuff 支持动态序列化和反序列化自定义消息类型,这使得它适用于各种场景。轻量级: Protostuff 只有很小的内存占用,使其适合内存受限的环境。兼容性: Protostuff 与标准 Protobuf 库完全兼容,可以读取和写入由其他 Protobuf 实现创建的二进制数据。

使用

要使用 Protostuff 序列化和反序列化 Protobuf 消息,请执行以下步骤:1. 编译 Protobuf 文件以生成消息类:```shellprotoc --java_out=OUTPUT_DIRECTORY path/to/protofile.proto```2. 在项目中添加 Protostuff 依赖项:```xml com.dyuproject.protostuff protostuff-core LATEST_VERSION ```3. 在代码中,使用 Protostuff 进行序列化:```javaProtostuffIOUtil.writeTo(message, output, schema);```4. 在代码中,使用 Protostuff 进行反序列化:```javaMessage message = new Message();ProtostuffIOUtil.mergeFrom(input, message, schema);```其中 `schema` 是由 `ProtobufCodecFactory` 提供的用于序列化和反序列化的消息模式。

性能基准

下表比较了 Protostuff和标准 Protobuf 实现的性能:| 操作 | Protostuff | Protobuf ||---|---|---|| 序列化 (1000 个消息) | 100 微秒 | 1 毫秒 || 反序列化 (1000 个消息) | 200 微秒 | 1.5 毫秒 |如您所见,Protostuff 在序列化和反序列化方面都明显快于标准 Protobuf 实现。

结论

Protostuff 是一个高性能的二进制序列化库,非常适合需要快速、可扩展和轻量级序列化和反序列化 Protobuf 消息的应用程序。它提供了比标准 Protobuf 实现更高的性能,同时仍然保持兼容性和功能。要了解更多信息并下载 Protostuff,请访问其 [官方网站](。

二进制json协议有哪些

二进制JSON协议主要有以下几种:是一种由Google开发的二进制序列化协议,它具有高效、紧凑、可扩展等优点,被广泛应用于高性能、高吞吐量的数据传输和存储中。 -rpc:是一种基于JSON的远程过程调用协议,它使用JSON作为数据交换格式,具有简单、易用、跨平台等优点。 json-rpc协议使用JSON编码和解码来实现数据传输和解析。 :是一种二进制序列化协议,它具有高效、紧凑、跨语言等优点,被广泛应用于分布式系统中。 msgpack使用二进制编码和解码来实现数据传输和解析。 ’nproto:是一种由开发的二进制序列化协议,它具有高效、紧凑、可扩展等优点,被广泛应用于高性能、高吞吐量的数据传输和存储中。 cap’nproto使用二进制编码和解码来实现数据传输和解析。

Protobuf协议实现原理

protobuf 是Google开源的一款支持跨平台、语言中立的结构化数据描述和高性能序列化协议,此协议完全基于二进制,所以性能要远远高于JSON/XML。由于出色的传输性能所以常见于微服务之间的通讯,其中最为著名的是Google开源的gRPC框架。

那么protobuf是如何实现高性能的,又是如何实现数据的编码和解码的呢?

基于128bits的数据存储方式(Base 128 Varints)

Varint 是一种紧凑的表示数字的方法。它用一个或多个字节来表示一个数字,值越小的数字使用越少的字节数。这能减少用来表示数字的字节数。

比如对于 int32 类型的数字,一般需要 4 个 byte 来表示。但是采用 Varint,对于很小的 int32 类型的数字,则可以用 1 个 byte 来表示。当然凡事都有好的也有不好的一面,采用 Varint 表示法,大的数字则需要 5 个 byte 来表示。从统计的角度来说,一般不会所有的消息中的数字都是大数,因此大多数情况下,采用 Varint 后,可以用更少的字节数来表示数字信息

Varint 中的每个 byte 的最高位 bit 有特殊的含义,如果该位为 1,表示后续的 byte 也是该数字的一部分,如果该位为 0,则结束。其他的 7 个 bit 都用来表示数字。因此小于 128 的数字都可以用一个 byte 表示。大于 128 的数字,比如 300,会用两个字节来表示:1010 1100 0000 0010。

Protobuf 的高性能二进制序列化库:protostuff (protobuf序列化和反序列化) 第1张

另外如果从数据大小角度来看,这种表示方式比实现的数据多了一个bit, 所以其实际传输大小就多14%(1/7 = 0.)。

数字1表示方式:0000 0001

对于小的数据比较好理解,正常情况下1的二进制是 0000 0001,使用128bits表示的话,首位结束标识位也是0,所以两者结果是一样的 0 000 0001。

数字 300 表示方式:1010 1100 0000 0010

这个有点不太好理解了,这是因为原本用一个字节(8bit)就可以表示,但由于使用128bits表示方法,需要对每个字节的最高位添加一个结束标识位来表示,所以一个字节已经不够用了,需要占用两个字节来表示,其中两个字节最高位都是结束标识位。

如果正向推算的话,我们知道数字300的二进制值 1 0010 1100,用两个字节表示完整值则为 0000 0001 0010 1100 # 二进制 _000 0010 _010 1100 # 二进制每个字节的最高位向左移动一个位置,放入结束标识位 0 000 0010 1 010 1100 # 转换为128bits方式,1:结束,0:未结束 1 010 1100 0 000 0010 # 转换为 小端字节序 , 低字节在前,高字节在后

注意这里是先添加结束标识符,然后再转为小端字节序。

消息经过序列化后会成为一个二进制数据流,该流中的数据为一系列的 Key-Value 对。如下图所示:

采用这种 Key-Pair 结构无需使用分隔符来分割不同的 Field。 对于可选的 Field,如果消息中不存在该 field,那么在最终的 Message Buffer 中就没有该 field ,这些特性都有助于节约消息本身的大小。

Key 用来标识具体的 field,在解包的时候,客户端创建一个结构对象,Protocol Buffer 从数据流中读取并反序列化数据,并根据 Key 就可以知道相应的 Value 应该对应于结构体中的哪一个 field。

而Key也是由以下两部分组成

Key 的定义如下:

| 1 |(field_number << 3) | wire_type|

可以看到 Key 由两部分组成。第一部分是 field_number 。第二部分为 wire_type 。表示 Value 的传输类型。

一个字节的低3位表示数据类型,其它位则表示字段序号。

Wire Type 可能的类型如下表所示:

在我们的例子当中,field id 所采用的数据类型为 int32,因此对应的 wire type 为 0。细心的读者或许会看到在 Type 0 所能表示的数据类型中有 int32 和 sint32 这两个非常类似的数据类型。Google Protocol Buffer 区别它们的主要意图也是为了减少 encoding 后的字节数。

每个数据头同样采用128bits方式,一般1个字节就足够了,

本例中字段a 的 序号是1

如上创建了 Test1 的结构并且把 a 的值设为 2,序列化后的二进制数据为 0 000 1000 0 000 0010

Key 部分是 0000 1000 value 部分是 0000 0010, 其中字节最高位是结束标识位,即10进制的2,我们在转换的时候统一将符号位转为0即可。

协议规定数据头的低3位表示wire_type, 其它字段表示字段序号field_number,因此 0000 1000 _000 1000 # 去掉结束标识符位 _000 1000 # 000 表示数据类型, 这里是Varint _000 1000 # 0001 这四位表示字段序号

原文:

java序列化Protostuff和Serializable的区别

序列化就是将Java Object转成byte[];反序列化就是将byte[]转成Java Object。 Java自带序列化机制标识一个对象需要系列化,该对象类型需要实现 Serializable 接口。 1,序列化的类型和反序列化的类型的序列化ID必须一致(远程信息交换时)。 2,静态数据不会被序列化,Transient关键字修饰的字段不会被序列化。 3,对象序列化存储时,两次存储相同值对象会有优化(第二次对象写入会只存储引用)。 Protostuff是一个序列化库,支持一下序列化格式:protobufprotostuff (native)graph (protostuff with support for cyclic references. See Serializing Object Graphs)jsonsmile (binary json useable from the protostuff-json module)xmlyaml (serialization only)kvp (binary uwsgi header)序列化@SuppressWarnings(unchecked)public static <T> byte[] serialize(T obj) {Class<T> cls = (Class<T>) ();//获得对象的类;LinkedBuffer buffer = (_BUFFER_SIZE);//使用LinkedBuffer分配一块默认大小的buffer空间;try {Schema<T> schema = getSchema(cls);//通过对象的类构建对应的schema;return (obj, schema, buffer);//使用给定的schema将对象序列化为一个byte数组,并返回。 } catch (Exception e) {throw new IllegalStateException((), e);} finally {();}}反序列化public static <T> T deserialize(byte[] data, Class<T> cls) {try {T message = (cls);//使用objenesis实例化一个类的对象;Schema<T> schema = getSchema(cls);//通过对象的类构建对应的schema;(data, message, schema);//使用给定的schema将byte数组和对象合并,并返回。 return message;} catch (Exception e) {throw new IllegalStateException((), e);}}优缺点比较:优点 缺点Serializable 使用方便,可序列化所有类 速度慢,占空间Protostuff 速度快,基于protobuf 需静态编译

若对本页面资源感兴趣,请点击下方或右方图片,注册登录后

搜索本页相关的【资源名】【软件名】【功能词】或有关的关键词,即可找到您想要的资源

如有其他疑问,请咨询右下角【在线客服】,谢谢支持!

Protobuf 的高性能二进制序列化库:protostuff (protobuf序列化和反序列化) 第2张

发表评论

评论列表

  • 这篇文章还没有收到评论,赶紧来抢沙发吧~
你上次访问网站的时间为:24-05-17,14:53:12 你第2访问网站的时间为:24-05-17 14:53:13