Json?OR FlatBuffers?FlatBuffers

FlatBuffers in Android - introduction

JSON - probably everyone knows this lightweight data format used in
almost all modern servers. It weights less, is more human-readable and
in general is more dev-friendly than old-fashined, horrible xml. JSON
is language-independend data format but parsing data and transforming
it to e.g. Java objects costs us time and memory resources. Several
days ago Facebook announced big performance improvement in data
handling in its Android app. It was connected with dropping JSON
format and replacing it with FlatBuffers in almost entire app. Please
check this article to get some basic knowledge about FlatBuffers and
results of transition to it from JSON.

While the results are very promising, at the first glance the
implementation isn’t too obvious. Also facebook didn’t say too much.
That’s why in this post I’d like to show how we can start our work
with FlatBuffers.

到这里可能有的人估计可能头晕了,我去,这么多英语,其实没事啦,找个翻译软件对不对, 大概的意思就是JSON -
可能每个人都知道几乎所有现代服务器都使用这种轻量级的数据格式。键值对Map–>Value
它的权重更少,更易于人阅读,一般来说比旧的,可怕的xml更友好。 JSON是独立于语言的数据格式,但解析数据并将其转换为
Java对象花费了我们的时间和内存资源。 几天前,Facebook在其Android应用程序中宣布了大幅提高数据处理的性能。
它与丢弃JSON格式连接,并替换为FlatBuffers几乎整个应用程序。

虽然结果非常有前途,乍一看,实施并不太明显。 另外Facebook没有说太多。
这就是为什么我在这篇文章中,我想展示我们如何开始我们的工作与FlatBuffers。

Json与FlatBuffers区别
Json与 FlatBuffer的区别在于,它在平坦的二进制缓冲区中表示分层数据,使得它仍然可以在没有解析/解包的情况下直接访问,同时还支持数据结构演进(向前/向后兼容)

简而言之,FlatBuffers是一个来自谷歌的跨平台序列化库,专门用于游戏开发,正如Facebook所示,遵循Android平滑和响应式UI的16ms规则。

但是,在你把所有的数据迁移到FlatBuffers之前,只是确保你需要这个。有时,对性能的影响将是不可察觉的,有时数据安全将比计算速度上的几十毫秒的差异更重要。

什么使FlatBuffers如此有效?

序列化数据由于平坦的二进制缓冲区而被访问而不进行解析,即使对于分层数据也是如此。由于这个,我们不需要初始化解析器(意味着构建复杂的字段映射)和解析这些数据,这也需要时间。
FlatBuffers数据不需要分配比缓冲区本身使用的内存更多的内存。我们不需要为解析数据的整个层次分配额外的对象,就像在JSON中做的那样。
对于实数,只需再次检查Facebook文章有关迁移到FlatBuffers或Google文档本身
实现
JSON数据在应用程序外部的某处转换为FlatBuffer格式(例如,bin ary二进制文件作为文件传递或直接从API返回)
数据模型(Java类)是手工生成的,用flatc(FlatBuffer编译器)
JSON文件有一些限制(空字段不能使用,日期格式解析为字符串)
也许在将来我们将准备更复杂的解决方案。

FlatBuffers 编译器
在开始,我们必须得到flatc - FlatBuffers编译器。 它可以从Google的flatbuffers仓库中托管的源代码构建。 让我们下载/克隆它。 整个构建过程在FlatBuffers构建文档中描述。 如果你是Mac用户所有你需要做的是:

在\ {extract directory} \ build \ XcodeFlatBuffers.xcodeproj上打开下载的源代码
按播放按钮或⌘+ R运行flatc方案(默认情况下应选择)
flatc可执行文件将出现在项目根目录中。
现在我们可以使用模式编译器,其中可以为给定模式(在Java,C#,Python,GO和C ++)生成模型类或将JSON转换为FlatBuffer二进制文件。
模式文件
现在我们必须准备模式文件,它定义我们想要去序列化的数据结构。 此模式将与flatc一起使用以创建Java模型并将JSON转换为Flatbuffer二进制文件。

这里是我们的JSON文件的一部分:

完整版本在这里。 这是一个有点修改版本的数据,可以从Github API调用:https://api.github.com/users/google/repos

写一个FlatBuffer模式是非常好的文档,所以我不会深入这。 在我们的情况下,模式也不会很复杂。 我们要做的是创建3个表:ReposList,Repo和User,并定义root_type。 这里是这个模式的重要部分:

此处提供完整模式文件。

FlatBuffers数据文件
现在我们要做的是将repos_json.json转换为FlatBuffers二进制文件,并生成Java模型,这将能够以Java友好的方式表示我们的数据(此操作中需要的所有文件都在我们的存储库中可用):

$ ./flatc -j -b repos_schema.fbs repos_json.json

If everything goes well, here is a list of generated files:

repos_json.bin (we’ll rename it to repos_flat.bin)
Repos/Repo.java
Repos/ReposList.java
Repos/User.java

现在让我们创建我们的示例应用程序,以检查FlatBuffers格式在实践中如何工作。 这里是它的截图:
这里写图片描述
进度条将仅用于显示不正确的数据处理(在UI线程中)如何影响用户界面的平滑度

app/build.gradle file of our app will look like this:

当然,在我们的例子中没有必要使用Rx或ButterKnife,但为什么不让这个应用程序更好一点?

让我们把repos_flat.bin和repos_json.json文件放到res / raw /目录下。

这里是RawDataReader实用程序,它帮助我们在Android应用程序中读取原始文件。

最后把Repo,ReposList和User放在项目的源代码中。

FlatBuffers库
FlatBuffers提供了java库来直接在java中处理这种数据格式。 这里是flatbuffers-java-1.2.0-SNAPSHOT.jar文件。 如果你想手动生成它,你必须回到下载的FlatBuffers源代码,去java /目录,并使用Maven来生成这个库:

$ mvn install
Now put .jar file to your Android project, into app/libs/ directory.

现在把.jar文件放到你的Android项目中,放到app / libs /目录下。

好了,现在我们要做的就是实现MainActivity类。 这里是它的完整的源代码:

我们最感兴趣的方法:

parseReposListJson(String reposStr) - 此方法初始化Gson解析器并将json String转换为Java对象。
loadFlatBuffer(byte [] bytes) - 此方法将字节(我们的repos_flat.bin文件)转换为Java对象。
结果:
现在让我们看看JSON和FlatBuffers之间的差异加载时间和消耗的资源。 测试是在安装了Android M(测试版)的Nexus 5上结果如下图
加载时间
测量的操作是转换为Java文件和迭代所有元素。

JSON - 200ms(范围:180ms - 250ms) - 我们的JSON文件的平均加载时间(权重:478kB)FlatBuffers - 5ms(范围:3ms - 10ms) - 平均加载时间的FlatBuffers二进制文件

还记得我们的16ms规则吗? 我们在UI线程中用一个原因调用这些方法。 看看我们的界面在这种情况下的行为:

JSON loading:
这里写图片描述
FlatBuffer loading:
这里写图片描述
看到不同没有? Json加载冻结进度条一段时间,使我们的界面不愉快(操作需要超过16ms)。哈哈!

分配,CPU等
想要衡量更多吗? 也许这是一个好时机,试试Android Studio 1.3和新功能,如分配跟踪,内存查看器和方法跟踪。
到这里基本结束了!需要学习自己扫码进群讨论!期待你们的到来!
【疯狂Android进阶之旅】:https://jq.qq.com/?_wv=1027&k=46pnd9b

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值