java flatbuffers_[Java教程]FlatBuffers 使用小结

[Java教程]FlatBuffers 使用小结

0 2021-01-14 18:00:52

最近做一个Android APP,由于离线业务需求,需要在启动APP时候同步大量数据到APP上,遇到了JSON性能瓶颈。从下方的图片中可以看出,当使用 json 传输数据,在解析json的时候会产生大量的对象,使得内存疯狂飙升,不论是配置低端的平板还是配置比较高端的手机都会 GC 。而在使用 flatbuffers 的时候不论是平板还是手机,都没有 GC,并且在时间是数量级的差别。0.5s与0.05s的差距对你而言或许并不大,但是1s和10s的差距就很明显了噻,应该没人能忍受一个app的反应时间需要10s之久吧...

下面是我测试的参数与测试结果,对比提升可以说是相当的明显了。注(这里的解析时间是指:从发起请求到响应后把数据解析成对象的时间,也就是说除去相差不多的网络传输时间,单纯的对数据的解析时间 faltbuffers 提升会更加明显 )

bc91bb04e6e9c61e24c974e4440db8f2.gif

bc91bb04e6e9c61e24c974e4440db8f2.gif

什么是 FlatBuffers ?

FlatBuffers是一个高效的跨平台序列化库,适用于C++, C#, C, Go, Java, Kotlin, JavaScript, Lobster, Lua, TypeScript, PHP, Python, Rust 和Swift。它们最早由谷歌创立,用来开发游戏和其他一些需要高性能的程序。

为什么使用 FlatBuffers 会这么快?

无需解析/拆包即可访问序列化数据-FlatBuffers的与众不同之处在于,它在平坦的二进制缓冲区中表示层次结构数据,使得无需解析/拆包就可以直接访问它,同时还支持数据结构的演进(forward /向后兼容)

如何使用 FlatBuffers ?

1.编译器下载地址:https://github.com/google/flatbuffers/releases

bc91bb04e6e9c61e24c974e4440db8f2.gif

2.编写Schema文件 demo.fbsnamespace com.zxz.demo.flatbuffer;table User {id : long;name : string;gender : string;departmentId : long;createTime : string;enabled : bool;status : string;}table Account {id : long;userId : long;login : string;password : string;loginCount : int;}table Data {userList : [User];accountList : [Account];}root_type Data;

3.生成javaBean文件:flatc.exe --java demo.fbs

bc91bb04e6e9c61e24c974e4440db8f2.gif

bc91bb04e6e9c61e24c974e4440db8f2.gif

4.下载 FlatBuffers 源码:  https://github.com/google/flatbuffers/tree/master/java,或者看看maven仓库有没有依赖包引入项目

5.服务端创建数据public void service() throws Exception { HttpServletResponse response = ActionContext.get().getResponse(); // 1.创建builder FlatBufferBuilder builder = new FlatBufferBuilder(1024); List list1 = new ArrayList(); for (int i = 0; i < 10; i++) { long id = 0L; int nameOffset = builder.createString("name"); int genderOffset = builder.createString("gender"); long departmentId = 0L; int createTimeOffset = builder.createString("2021-01-10"); boolean enabled = true; int statusOffset = builder.createString("status"); // 2.创建User对象返回 offset值 int createUser = User.createUser(builder, id, nameOffset, genderOffset, departmentId, createTimeOffset, enabled, statusOffset); list1.add(createUser); } // 3.把存储对象offset值的集合转成数组 int[] arr1 = list1.stream().mapToInt(Integer::valueOf).toArray(); // 4.构建User的数据 int createUsersVector = Data.createUsersVector(builder, arr1); // 5.构建Data对象(Data中包含[User]) Data.startData(builder); // 6.添加User的集合 Data.addUsers(builder, createUsersVector); int offset = Data.endData(builder); Data.finishDataBuffer(builder, offset); // 7.把DataBuffer写入到IO中 ServletOutputStream os = response.getOutputStream(); os.write(builder.dataBuffer().array(), builder.dataBuffer().position(), builder.offset()); os.close();}

6.客户端接收数据public void onResponse(Call call, Response response) throws IOException {

byte[] bytes = response.body().bytes(); ByteBuffer bb = ByteBuffer.wrap(bytes); Data data = Data.getRootAsData(bb);}

==================================END==================================

==============================测试结果截图===============================

图一、平板上使用 json 传输数据

bc91bb04e6e9c61e24c974e4440db8f2.gif

图二、手机上使用 json 传输数据

bc91bb04e6e9c61e24c974e4440db8f2.gif

图三、平板上使用 flatbuffers 传输数据

bc91bb04e6e9c61e24c974e4440db8f2.gif

图四、手机上使用 flatbuffers 传输数据

bc91bb04e6e9c61e24c974e4440db8f2.gif

本文网址:http://www.shaoqun.com/a/508856.html

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:admin@shaoqun.com。

google谷歌Java网络Javascriptandroidc#phpc++

0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值