JSON与Protocol Buffers的一些比较

转载来源:http://www.cnblogs.com/zhubo/archive/2011/07/06/JSON_And_ProtocolBuffers.html

 

JSON与Protocol Buffers的一些比较

前言

  • 习惯用 Json、XML 数据存储格式的你们,相信大多都没听过Protocol Buffer
  • Protocol Buffer 其实 是 Google出品的一种轻量 & 高效的结构化数据存储格式,性能比 Json、XML 真的高很多!

JSONProtocol Buffers同为序列化数据的存储格式。性能比较,视平台、语言、数据结构复杂程度的不同,Protocol Buffers与JSON相比,ProtoBuffer性能可能会很多。JSON数据格式有一个缺点:冗余太大,如:

[{"CName": "Tom", "Gender": 0}, {"CName": "Tomsam", "Gender": 1}]

JSON格式的数据,每条记录都要包括"CName"和"Gender",据一些统计,JSON格式的数据至少有20%左右是无效的。

与JSON不同,Protocol Buffers用二进制编码数据,而且数据的格式是事先通过一个后缀名为.proto的文件指定的,如:

message Person {
  required string CName = 1;
  optional int32 Gender = 2;
}

这样Protocol Buffers的数据信息会比JSON少很多,在一些场景,比如内存里要存储更多的数据时,ProtoBuffer或许是一个不错的选择。

作用

通过将 结构化的数据 进行 串行化(序列化),从而实现 数据存储 / RPC 数据交换的功能

  1. 序列化: 将 数据结构或对象 转换成 二进制串 的过程
  2. 反序列化:将在序列化过程中所生成的二进制串 转换成 数据结构或者对象 的过程

 

特点

  • 对比于 常见的 XML、Json 数据存储格式,Protocol Buffer有如下特点:

(a)占用空间小
一条消息数据,用protobuf序列化后的大小是json的10分之一,xml格式的20分之一,是二进制序列化的10分之一(极端情况下,会大于等于直接序列化),总体看来ProtoBuf的优势还是很明显的。
(b)解析速度快
解析速度快,主要归功于protobuf对message 没有动态解析,没有了动态解析的处理序列化速度自然快了。就比如xml ,获取文件之后,还需要解析标签、节点、字段,每一个都需要遍历,而protobuf不需要,直接将field装入流。
(c)兼容性好
fieldNumber 为每个field定义一个编号,其一保证不重复,其二保证其在流中的位置。如若当前数据流中有某个字段,而解析方没有相关的解析代码,解析放会直接skip 吊这个field,而且读数据的position也会后移,保证后续读取不出问题。
参考来源:https://blog.csdn.net/ljun_1129/article/details/77370659 

应用场景

传输数据量大 & 网络环境不稳定 的数据存储、RPC 数据交换 的需求场景,在 传输数据量较大的需求场景下,Protocol BufferXML、Json 更小、更快、使用 & 维护更简单!

扫描二维码关注公众号,回复: 4737283 查看本文章

如 即时IM (QQ、微信)的需求场景

上述文章,部分资料参考来源:https://blog.csdn.net/aptentity/article/details/68228071

性能测试:

Android 应用程序必须访问位于 Internet 上的数据,而 Internet 数据可以有几种不同的格式。本文将介绍在 Android 应用程序中如何使用三种数据格式:

  • XML
  • JSON
  • Google 的 protocol buffers

首先开发一个 Web 服务,将 CSV 数据转换成 XML、JSON 和 protocol-buffers 格式。然后构建一个样例 Android 应用程序,可以从 Web 服务中以任何一种格式提取数据并将其解析并显示给用户。要进行本文中的练习,您需要最新的 Android SDK(参见 参考资料)和 Android 2.2 平台。SDK 还要求您安装一个 Java™ 开发包(JDK);本文中使用了 JDK 1.6.0_17。您不需要有 Android 物理设备;所有代码都将在 SDK 的 Android 仿真器中运行。本文并没有教您如何进行 Android 开发,因此建议您熟悉 Android 编程。当然,只凭借 Java 编程语言的知识也可以完成本文的学习。您还需要一个 Java web 应用程序服务器来运行 Android 应用程序使用的 Web 服务。此外,也可以将服务器端代码部署到 Google App Engine。参见 下载 部分获得完整的源代码。

性能比较

比较性能通常涉及某种微基准测试,此类基准测试很容易产生偏见或无意间得到不正确的结果。即使以公平方式设计微基准测试,很多随机因素也会对结果产生影响。尽管有这些问题,我还是要使用这样的微基准测试来比较 XML(大约 1300 ms)、JSON(大约 1150 ms)和 protocol buffers(大约 750 ms)。基准测试向服务器发送了一个关于 200 个股票的请求并测量了从发出请求到用于创建 ListView 的Adapter 的数据准备就绪所需的时间量。对每个数据格式在两个设备上进行 50 次这样的操作:一个 Motorola Droid 和一个 HTC Evo,两个都通过 3G 网络。 图 2 显示了结果:

图 2. 比较数据格式速度 
fig02

图 2 显示出,在此基准测试中 protocol buffers(大约 750 ms)比 XML (大约 1300 ms)几乎快两倍。很多因素影响着数据通过网络和被手持设备处理的性能。一个明显的因素是通过网络的数据量。二进制格式的 protocol buffers 比文本格式的 XML 和 JSON 在通过网络时小得多。然而,文本格式可以使用 gzip 进行有效地压缩,这是 Web 服务器和 Android 设备都支持的标准技术。 图 3 显示了在打开和关闭 gzip 时通过网络的数据大小:

图 3. 不同格式的数据大小 
fig03

图 3 应该增加了您对 XML 和 JSON 之类的文本内容的压缩效果的喜爱(更不用说 Web 格式、HTML、JavaScript 和 CSS 了)。protocol buffers 数据(大约 6KB)比原始 XML(大约 17.5KB)或 JSON(大约 13.5KB)数据小得多。但是一旦进行了压缩, JSON 和 XML(都是大约 3KB)实际上比 protocol buffers 小很多了。在本例中,它们都接近于 protocol-buffers 编码消息大小的一半了。

回到 图 2,速度的不同显然不能由通过网络的消息大小解释。protocol-buffers 消息比 XML 或 JSON 编码的消息大,但是通过使用 protocol buffers,您仍然能够削减半秒钟的用户等待时间。这是否意味着应该在 Android 应用程序中使用 protocol buffers 呢?这样的决定很少是固定的。如果要发送的数据量很小,则三种格式间的差异也不大。对于大量数据而言,protocol buffers 可能会有所不同。但是,像这样精心设计的基准测试无法替代对您自己的应用程序的测试。

本文介绍了如何使用 Internet 上流行的两种数据格式 XML 和 JSON 的方方面面。还讲到了第三种可能性,protocol buffers。像软件工程中的其他内容一样,选择技术主要就是权衡利弊。当您为一个局限的环境(比如 Android)开发时,这些决定的结果往往被放大了。我希望您现在拥有的关于这些后果的额外知识能够帮助您创建出色的 Android 应用程序。

上述文章,部分资料参考来源:https://blog.csdn.net/zhyooo123/article/details/50245799

总结

1、json: 一般的web项目中,最流行的主要还是json。因为浏览器对于json数据支持非常好,有很多内建的函数支持。 
2、xml: 在webservice中应用最为广泛,但是相比于json,它的数据更加冗余,因为需要成对的闭合标签。json使用了键值对的方式,不仅压缩了一定的数据空间,同时也具有可读性。 
3、protobuf:是后起之秀,是谷歌开源的一种数据格式,适合高性能,对响应速度有要求的数据传输场景。因为profobuf是二进制数据格式,需要编码和解码。数据本身不具有可读性。因此只能反序列化之后得到真正可读的数据。

相对于其它,Protobuf更具有优势 

1:序列化后体积相比Json和XML很小,适合网络传输 
2:支持跨平台多语言 
3:消息格式升级和兼容性还不错 
4:序列化反序列化速度很快,快于Json的处理速速
PS:在一个需要大量的数据传输的场景中,如果数据量很大,那么选择protobuf可以明显的减少数据量,减少网络IO,从而减少网络传输所消耗的时间。

上述文章,部分资料转载来源:https://blog.csdn.net/u014043213/article/details/80336805 
 

其他资料:

ProtoBuf.js是基于ByteBuffer.js的Protocol Buffers纯Javascript实现。主要功能是解析.proto 文件,构建message类,和简单的编码、解码。目前在一个node-webkit中使用protobuf格式于服务端进行数据交互(服务端是按照旧c++客户端要求实现的protobuf)。

目前对ProtoBuf.js的使用主要就是读取旧的.proto 文件,创建message类,编码,发送给服务端,如下:

user.proto 文件:

  1. package protobuf;
  2. message UserModel {
  3. required string cyUserno = 1;
  4. required string cyPassWord = 2;
  5. required string cyStatus = 3;
  6. }

nodejs代码:

  1. var fs = require("fs"),
  2. ProtoBuf = require("protobufjs"),
  3. userProtoStr = fs.readFileSync('./user.proto').toString(),
  4. UserModel = ProtoBuf.loadProto(userProtoStr).build('protobuf').UserModel,
  5. userModel;
  6. userModel= new UserModel();
  7. userModel.set('cyUserno', '111111');
  8. userModel.set('cyPassWord', '123456');
  9. userModel.set('cyStatus', '1');
  10. var buffer = userModel.encode().toBuffer();

解码的方法也很简单:

  1. var userInfo = UserModel.decode(data);
  2. userInfo.get('cyUserno');
  3. ......

另外protobuf.js还提供了一些工具,例如.proto 和.json 的转换等,具体参看他的官网:https://github.com/dcodeIO/ProtoBuf.js

其他资料,转载来源:http://keenwon.com/1304.html

其他资料:

你可能会问,既然我们已经有很标准的JSON以及转换库比如GSON和Jackson,为什么还要使用新的工具呢?

不妨先试一下FlatBuffers,然后你就会发现它比JSON快得多。

FlatBuffers是什么?

FlatBuffers是一个高效的跨平台序列化类库,可以在C++、C#、C、Go、Java、JavaScript、PHP和Python中使用。是Google开发的,是为了应用在游戏开发,以及其他注重性能的应用上。

为什么要使用FlatBuffers?

  • 不需要解析/拆包就可以访问序列化数据 — FlatBuffers与其他库不同之处就在于它使用二进制缓冲文件来表示层次数据,这样它们就可以被直接访问而不需解析与拆包,同时还支持数据结构进化(前进、后退兼容性)。

  • 内存高效速度快 — 访问数据时只需要访问内存中的缓冲区。它不需要多余的内存分配(至少在C++是这样,其他语言中可能会有变动)。FlatBuffers还适合配合 mmap或数据流使用,只需要缓冲区的一部分存储在内存中。访问时速度接近原结构访问,只有一点延迟(一种虚函数表vtable),是为了允许格式升级以 及可选字段。FlatBuffers适合那些花费了大量时间和空间(内存分配)来访问和构建序列化数据的项目,比如游戏以及其他对表现敏感的应用。可以参 考这里的基准

  • 灵活 — 由于有可选字段,你不但有很强的升级和回退兼容性(对于历史悠久的游戏尤其重要,不用为了每个版本升级所有数据),在选择要存储哪些数据以及设计数据结构时也很自由。

  • 轻量的code footprint — FlatBuffers只需要很少量的生成代码,以及一个表示最小依赖的很小的头文件,很容易集成。细节上可以看上面的基准页。

  • 强类型 — 编译时报错,而不需要自己写重复的容易出错的运行时检查。它可以自动生成有用的代码。

  • 使用方便 — 生成的C++代码允许精简访问与构建代码。还有可选的用于实现图表解析、类似JSON的运行时字符串展示等功能的方法。(后者比JSON解析库更快,内存效率更高)

  • 代码跨平台且没有依赖 — C++代码可以运行在任何近代的gcc/clang和VS2010上。同时还有用于测试和范例的构建文件(Android中.mk文件,其他平台是cmake文件)。

都有谁使用FlatBuffers?

  • BobbleApp,印度第一贴图App。我们在BobbleApp中使用FlatBuffers后App的性能明显增强。

  • Cocos2d-x,第一开源移动游戏引擎,使用FlatBuffers来序列化所有的游戏数据。

  • Facebook使用FlatBuffers在Android App中进行客户端服务端的沟通。他们写了一篇文章来描述FlatBuffers是如何加速加载内容的。

  • Google的Fun Propulsion Labs在他们所有的库和游戏中大量使用FlatBuffers。

App性能有多大提高?

  • 解析速度 解析一个20KB的JSON流(这差不多是BobbleApp的返回大小)需要35ms,超过了UI刷新间隔也就是16.6ms。如果解析JSON的话,我们就在滑动时就会因为要从磁盘加载缓存而导致掉帧(视觉上的卡顿)。

  • 解析器初始化 一个JSON解析器需要先构建字段映射再进行解析,这会花100ms到200ms,很明显的拖缓App启动时间。

  • 垃圾回收 在解析JSON时创建了很多小对象,在我们的试验中,解析20kb的JSON流时,要分配大约100kb的瞬时存储,对Java内存回收造成很大压力。

FlatBuffers vs JSON

我尝试使用FlatBuffers和JSON解析4mb的JSON文件。

FlatBuffers花了1-5ms,JSON花了大约2000ms。在使用FlatBuffers期间Android App中没有GC,而在使用JSON时发生了很多次GC。在使用JSON时UI完全卡住,所以真实使用时只能在后台线程进行解析。

github源码地址:https://github.com/amitshekhariitbhu/FlatBuffer

其他资料,转载来源:http://www.mamicode.com/info-detail-1434601.html

参考:

[1], Serializing Data - JSON vs. Protocol Buffers 

[2], 构建高性能的微博系统——再谈新浪微博架构

[3], https://blog.csdn.net/aptentity/article/details/68228071

猜你喜欢

转载自blog.csdn.net/Aria_Miazzy/article/details/85537808