最近做一個Android APP,由于離線業務需求,需要在啟動APP時候同步大量資料到APP上,遇到了JSON性能瓶頸,從下方的圖片中可以看出,當使用 json 傳輸資料,在決議json的時候會產生大量的物件,使得記憶體瘋狂飆升,不論是配置低端的平板還是配置比較高端的手機都會 GC ,而在使用 flatbuffers 的時候不論是平板還是手機,都沒有 GC,并且在時間是數量級的差別,0.5s與0.05s的差距對你而言或許并不大,但是1s和10s的差距就很明顯了噻,應該沒人能忍受一個app的反應時間需要10s之久吧...
下面是我測驗的引數與測驗結果,對比提升可以說是相當的明顯了,注(這里的決議時間是指:從發起請求到回應后把資料決議成物件的時間,也就是說除去相差不多的網路傳輸時間,單純的對資料的決議時間 faltbuffers 提升會更加明顯 )


什么是 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

2.撰寫Schema檔案 demo.fbs
namespace 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


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<Integer> list1 = new ArrayList<Integer>();
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 傳輸資料

圖二、手機上使用 json 傳輸資料

圖三、平板上使用 flatbuffers 傳輸資料

圖四、手機上使用 flatbuffers 傳輸資料

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/248848.html
標籤:Java
上一篇:java物件的序列化與反序例化
