我第一次知道FlatBuffers是因为Facebook写的这篇Android的技术博客文章。它主要介绍了FlatBuffers对比JSON的优势,以及Facebook Android App应用了FlatBuffers后,衍生的数据和界面更新的工作流转模式。建议去读一读,作者还是一个中国人哦。

下面开始介绍了一下FlatBuffers,首先看看它和JSON的对比。

   

先引用GitHub frogermcs/FlatBuffs上的两张Gif效果图.

那个Loading菊花是干什么的呢?点击上下两个按钮开始数据解析,而数据解析是故意放在主线程上执行,而Loading菊花能直观的辨别解析过程有没有导致UI卡顿。

左图,点击"PARSE JSON"按钮是用的Gson解析了一个468KB的Json文件,耗时200-300ms。

右图,点击"USE FLATBUFFERS",是“解析”同样的Json数据但是用FlatBuffers特有的数据格式文件repos_flat.bin。耗时是<10ms。FlatBuffers“解析”的过程,Loading菊花一直保持着流畅的转动。

FlatBuffers到底有什么样的魔术,能比JSON快这么多呢?

其实FlatBuffers实际并没有做数据的解析,repos_flat.bin是按照FlatBuffers数据组织格式生成的Byte数组。

FlatBuffer的数据解析是靠一层层的offset偏移量的组合计算定位到数据在Byte数组的位置,进而获取目标数据的值 。所以FlatBuffer是需要什么数据,才解析什么数据,并不需要全量解析。

简单说,FlatBuffers分为vtable区和数据区。vtable区保存的是数据的偏移值,数据区保存的是具体的数据值。

FlatBuffers的优点和缺点

优点:

1. 数据都是从Byte数组中获取,减少解析过程的内存占用,减低了GC发生概率。

Memory Efficient Serialization Library,FlatBuffers是这么描述自己的。

这里有别人做的内存检测的数据

2. 无需全量解析,用到的数据才需要解析。

想象一个很长的ListView,并不需要在初始状态就把所有的数据都解析出来。滚动到可见状态的item的数据,才需要被解析。

缺点:

1. 数据获取都是偏移量计算的解析过程,嵌套层级深的数据,可能带来性能问题。

2. 不自行做数据缓存的话,每次获取同样的数据会有重复计算。

3. Byte数据安全性和完整性有顾虑。也有人专门写博客表明不会用FlatBuffer哈哈。

FlatBuffers的应用

FlatBuffers还可以“解析”JSON,实际是把JSON数据生成FlatBuffers格式的Byte数组。

如上图,中间的按钮“PARSE JSON(FLATBUFFERS)”点击执行后解析468KB同样的JSON文件,比Gson节省了约40%的耗时。

作为应用FlatBuffers的切入点,参考着的frogermsc GitHub Demo,我尝试把FlatBuffer解析JSON应用到工作项目中。

步骤:

1. 使用FlatBuffers需要引入2个SO和一个JAR,合计1MB;

2. 根据待解析的数据,要写一个schema文件如下,类似于protocolBuffer的.proto文件的作用;

namespace RankDetail;

table RankDetail {
code : int;
msg : string;
} root_type RankDetail;

3. 通过命令行,根据schema生成相关解析后数据读取的Java类,这个步骤也类似protocolBuffer;

遇到的问题:

1. schema文件的Key-value对的Key不能数字开头,如下的123key是不符合要求的;

原因是因为,FlatBuffers是直接获取schema文件内的这种key-value的key的值作为方法名字和变量名字,阿拉伯数字开头的变量名和方法名是不合法的。

namespace RankDetail;

table RankDetail {
code : int;
msg : string;
123key : string;
} root_type RankDetail;

2. 解析是在SO的native代码,遇到失败就会native crash,缺少有用的解析失败的日志信息,增加开发调试的难度和时间。

FlatBuffers最大的威力是解析他自家格式的Byte数组(参考文章开头的GIF对比),应用到正式环境的功能,需要后台请求返回的数据是FlatBuffers格式的Bytes数组。另外,FlatBuffers解析的容错性目前还有待完善提升。但以后,FlatBuffers会是减少内存占用、提升用户体验的利器。

FlatBuffers初探的更多相关文章

  1. 初探领域驱动设计(2)Repository在DDD中的应用

    概述 上一篇我们算是粗略的介绍了一下DDD,我们提到了实体.值类型和领域服务,也稍微讲到了DDD中的分层结构.但这只能算是一个很简单的介绍,并且我们在上篇的末尾还留下了一些问题,其中大家讨论比较多的, ...

  2. CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探

    CSharpGL(8)使用3D纹理渲染体数据 (Volume Rendering) 初探 2016-08-13 由于CSharpGL一直在更新,现在这个教程已经不适用最新的代码了.CSharpGL源码 ...

  3. 从273二手车的M站点初探js模块化编程

    前言 这几天在看273M站点时被他们的页面交互方式所吸引,他们的首页是采用三次加载+分页的方式.也就说分为大分页和小分页两种交互.大分页就是通过分页按钮来操作,小分页是通过下拉(向下滑动)时异步加载数 ...

  4. JavaScript学习(一) —— 环境搭建与JavaScript初探

    1.开发环境搭建 本系列教程的开发工具,我们采用HBuilder. 可以去网上下载最新的版本,然后解压一下就能直接用了.学习JavaScript,环境搭建是非常简单的,或者说,只要你有一个浏览器,一个 ...

  5. .NET文件并发与RabbitMQ(初探RabbitMQ)

    本文版权归博客园和作者吴双本人共同所有.欢迎转载,转载和爬虫请注明原文地址:http://www.cnblogs.com/tdws/p/5860668.html 想必MQ这两个字母对于各位前辈们和老司 ...

  6. React Native初探

    前言 很久之前就想研究React Native了,但是一直没有落地的机会,我一直认为一个技术要有落地的场景才有研究的意义,刚好最近迎来了新的APP,在可控的范围内,我们可以在上面做任何想做的事情. P ...

  7. 【手把手教你全文检索】Apache Lucene初探

    PS: 苦学一周全文检索,由原来的搜索小白,到初次涉猎,感觉每门技术都博大精深,其中精髓亦是不可一日而语.那小博猪就简单介绍一下这一周的学习历程,仅供各位程序猿们参考,这其中不涉及任何私密话题,因此也 ...

  8. Key/Value之王Memcached初探:三、Memcached解决Session的分布式存储场景的应用

    一.高可用的Session服务器场景简介 1.1 应用服务器的无状态特性 应用层服务器(这里一般指Web服务器)处理网站应用的业务逻辑,应用的一个最显著的特点是:应用的无状态性. PS:提到无状态特性 ...

  9. NoSQL初探之人人都爱Redis:(3)使用Redis作为消息队列服务场景应用案例

    一.消息队列场景简介 “消息”是在两台计算机间传送的数据单位.消息可以非常简单,例如只包含文本字符串:也可以更复杂,可能包含嵌入对象.消息被发送到队列中,“消息队列”是在消息的传输过程中保存消息的容器 ...

随机推荐

  1. 5 行 Python 代码调用电脑摄像头

    前提: 确保 python 中安装了 opencv-python 模块.如果没有安装,可以参考:https://pypi.org/project/opencv-python/ 进行安装.话不多少,直接 ...

  2. 设计模式之module模式及其改进

    写在前面 编写易于维护的代码,其中最重要的方面就是能够找到代码中重复出现的主题并优化他们,这也是设计模式最有价值的地方 <head first设计模式>里有一篇文章,是说使用模式的心智, ...

  3. python数据分析的工具环境

    python做数据分析的优势: 拥有大量的库为数据分析和处理提供了完整的工具链 随着库还在不断的增加的同时, 算法的实现也更加的创新.Numpy, matplotlib, scipy,scikit-l ...

  4. electron快速开始

    初学electron 接触了两周的electron,感觉还不错,以后pc端基本上可以用electron加壳写pc端应用了,可以用nodejs的模块,也可以用es6.7,还可以直接操作系统文件.基本上可 ...

  5. 在HTML中引用JavaScript中的变量

    和上次的代码几乎一样,但这次是引用已经写好的变量.主要功能和用法如下: document对象的getElementId方法得到HTML元素. HTML元素的value属性可以用来设置变量的值. 02. ...

  6. 如何判断Map中的key或value类型

    在上班写工具类时,遇到了一个问题,将xml文件的节点都放入map容器中时,map的value也是一个map,导致取map的value时,需要判断这个value的数据类型,用到了一下说的这些知识: 对于 ...

  7. c++ getline()和get()的区别

    1.方法get(char &)和get(void)提供不跳过空白的单字符输入功能:2.函数get(char * , int , char)和getline(char * , int , cha ...

  8. Hyperledger Fabric(v1.2.0)代码分析1——channel创建

    Hyperledger Fabric(v1.2.0)代码分析1--channel创建 0. e2e_cli Hyperledger Fabric提供了一个e2e的例子,该例中创建了一个基础的区块链网络 ...

  9. Django之自带认证

    自带登录实例 {% extends "layout/base.html" %} // 所有link {% block body %} <div id="contai ...

  10. Shell重新学习(忘光了)

    成功和失败都放同一个文件 调试shell