自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

使用 FlatBuffers 提高反序列化性能

大數(shù)據(jù) 數(shù)據(jù)可視化
FlatBuffers 和 Protobuf 一樣具有數(shù)據(jù)不可讀性,必須進(jìn)行數(shù)據(jù)解析后才能可視化數(shù)據(jù)。但是相比其它的序列化工具,F(xiàn)latBuffers最大的優(yōu)勢(shì)是反序列化速度極快,或者說無需解碼。

最近一直在尋找一個(gè)性能和資源占用兼具的序列化和反序列化工具,大多組織都是采用的 JSON, JSON 可以做到數(shù)據(jù)的前后兼容,并且更容易讓人理解和可視化,但 JSON 的性能相對(duì)更差,自身的元數(shù)據(jù)也會(huì)占用更多的存儲(chǔ)空間。

根據(jù)官網(wǎng)介紹FlatBuffers是一個(gè)高效的、跨平臺(tái)的序列化組件,保證數(shù)據(jù)向前向后兼容性,支持多種編程語言,是專門為游戲開發(fā)和其他性能關(guān)鍵的應(yīng)用而開發(fā)的。它與Protobuf確實(shí)比較相似,最主要的區(qū)別就是,F(xiàn)latBuffers并不需要一個(gè)轉(zhuǎn)換/解包的步驟就可以獲取原數(shù)據(jù)。

比如在游戲場(chǎng)景下的網(wǎng)絡(luò)通信中,玩家往往是對(duì)延遲非常敏感的(尤其是在FPS,Moba類游戲中),拋去網(wǎng)絡(luò)本身的網(wǎng)絡(luò)延遲不談,如果能夠降低數(shù)據(jù)解析(反序列化)的延遲,就能降低玩家操作的延遲感,提升游戲體驗(yàn)。

fb 到底能比 pb 快多少?

我自己做了一個(gè)測(cè)試,結(jié)果如下:fb的序列化要略慢于pb的序列化,但是fb的反序列化要遠(yuǎn)遠(yuǎn)超過pb的反序列化。

 Benchmark                       Mode  Cnt         Score         Error  Units
c.s.fb.SampleTest.deserialize thrpt 5 84352854.022 ± 4278679.805 ops/s
c.s.fb.SampleTest.serialize thrpt 5 316259.628 ± 2395.626 ops/s
c.s.pb.SampleTest.deserialize thrpt 5 1407501.471 ± 221477.754 ops/s
c.s.pb.SampleTest.serialize thrpt 5 396038.869 ± 81730.806 ops/s

測(cè)試過程很簡(jiǎn)單,主要分為序列化和反序列化兩部分,序列化比較簡(jiǎn)單,直接使用jmh執(zhí)行即可;反序列化首先需要把相應(yīng)序列化的二進(jìn)制數(shù)據(jù)寫入文件,靜態(tài)讀取二進(jìn)制文件數(shù)據(jù),進(jìn)行反序列化操作。

pb文件

syntax = "proto2";

package com.test.pb;

option java_outer_classname = "SampleProto";

message Sample {
optional uint32 intData = 1;
// 數(shù)據(jù)消息
optional uint64 longData = 2;
// string數(shù)據(jù)
optional string str1 = 3;
optional string str2 = 4;
optional string str3 = 5;
optional string str4 = 6;
optional string str5 = 7;
optional string str6 = 8;
optional string str7 = 9;
optional string str8 = 10;
// 數(shù)組
repeated string person = 11;
}

pb序列化

 @Benchmark
public static byte[] serialize() {
SampleProto.Sample.Builder builder = SampleProto.Sample.newBuilder();
List<String> list = new ArrayList<>();
for (int i = 0; i < 20; i++) {
list.add("中國經(jīng)濟(jì)復(fù)蘇+" + i);
}
byte[] bytes = builder.setIntData(100).setLongData(System.currentTimeMillis())
.setStr1("306bb851-9a0a-4b07-b22b-7ff49a2a60e1")
.setStr2("306bb851-9a0a-4b07-b22b-7ff49a2a60e2")
.setStr3("306bb851-9a0a-4b07-b22b-7ff49a2a60e3")
.setStr4("306bb851-9a0a-4b07-b22b-7ff49a2a60e4")
.setStr5("306bb851-9a0a-4b07-b22b-7ff49a2a60e5")
.setStr6("306bb851-9a0a-4b07-b22b-7ff49a2a60e6")
.setStr7("306bb851-9a0a-4b07-b22b-7ff49a2a60e7")
.setStr8("306bb851-9a0a-4b07-b22b-7ff49a2a60e8")
.addAllPerson(list).build().toByteArray();
return bytes;

}

pb反序列化

 @Benchmark
public static SampleProto.Sample deserialize() throws InvalidProtocolBufferException {
SampleProto.Sample builder = SampleProto.Sample.parseFrom(bytes);
return builder;
}

fb 文件

// 指定生成消息類的Java包
namespace com.test.fb;

// 消息
table Sample {
// int32數(shù)據(jù)
intData:int;
// 數(shù)據(jù)消息
longData:float;
// string數(shù)據(jù)
str1:string;
str2:string;
str3:string;
str4:string;
str5:string;
str6:string;
str7:string;
str8:string;
// 數(shù)組
person:[string];
}

fb序列化

@Benchmark
public static byte[] serialize() {
FlatBufferBuilder flatBufferBuilder = new FlatBufferBuilder();

int str1 = flatBufferBuilder.createString("306bb851-9a0a-4b07-b22b-7ff49a2a60e0");
int str2 = flatBufferBuilder.createString("306bb851-9a0a-4b07-b22b-7ff49a2a60e1");
int str3 = flatBufferBuilder.createString("306bb851-9a0a-4b07-b22b-7ff49a2a60e2");
int str4 = flatBufferBuilder.createString("306bb851-9a0a-4b07-b22b-7ff49a2a60e3");
int str5 = flatBufferBuilder.createString("306bb851-9a0a-4b07-b22b-7ff49a2a60e4");
int str6 = flatBufferBuilder.createString("306bb851-9a0a-4b07-b22b-7ff49a2a60e5");
int str7 = flatBufferBuilder.createString("306bb851-9a0a-4b07-b22b-7ff49a2a60e6");
int str8 = flatBufferBuilder.createString("306bb851-9a0a-4b07-b22b-7ff49a2a60e7");
int[] index = new int[20];
for (int i = 0; i < 20; i++) {
index[i] = flatBufferBuilder.createString("中國經(jīng)濟(jì)復(fù)蘇+" + i);
}
int vectorOfTables = flatBufferBuilder.createVectorOfTables(index);
int sample = Sample.createSample(flatBufferBuilder, 100, System.currentTimeMillis(),
str1, str2, str3, str4, str5, str6, str7, str8, vectorOfTables);
flatBufferBuilder.finish(sample);
return flatBufferBuilder.sizedByteArray();
}

fb反序列化

@Benchmark
public static Sample deserialize() {
return Sample.getRootAsSample(ByteBuffer.wrap(bytes));
}

以上數(shù)據(jù)生成的二進(jìn)制文件, pb 大小為 0.763kb,fb 大小為 1.076kb,fb 的存儲(chǔ)占用高出了將近 29%,當(dāng)然如果是純數(shù)字 pb
還會(huì)進(jìn)一步壓縮。

為什么 fb 的反序列化速度這么快?

要搞清楚反序列化快的原因,就得弄明白序列化的過程,因?yàn)榉葱蛄谢切蛄谢哪嫦虿僮鳌?/p>

FlatBuffers 把對(duì)象數(shù)據(jù),保存在一個(gè)一維的數(shù)組中,將數(shù)據(jù)都緩存在一個(gè) ByteBuffer
中,每個(gè)對(duì)象在數(shù)組中被分為兩部分。元數(shù)據(jù)部分:負(fù)責(zé)存放索引。真實(shí)數(shù)據(jù)部分:存放實(shí)際的值。然而 FlatBuffers
與大多數(shù)內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)不同,它使用嚴(yán)格的對(duì)齊規(guī)則和字節(jié)順序來確保 buffer 是跨平臺(tái)的。此外,對(duì)于 table 對(duì)象,F(xiàn)latBuffers
提供前向/后向兼容性和 optional
字段,以支持大多數(shù)格式的演變。除了解析效率以外,二進(jìn)制格式還帶來了另一個(gè)優(yōu)勢(shì),數(shù)據(jù)的二進(jìn)制表示通常更具有效率。我們可以使用 4 字節(jié)的 UInt 而不是 10
個(gè)字符來存儲(chǔ) 10 位數(shù)字的整數(shù)。

圖片

FlatBuffers 對(duì)序列化基本使用原則:

  • 小端模式。FlatBuffers對(duì)各種基本數(shù)據(jù)的存儲(chǔ)都是按照小端模式來進(jìn)行的,因?yàn)檫@種模式目前和大部分處理器的存儲(chǔ)模式是一致的,可以加快數(shù)據(jù)讀寫的數(shù)據(jù)。
  • 寫入數(shù)據(jù)方向和讀取數(shù)據(jù)方向不同。

簡(jiǎn)單來說, fb 在進(jìn)行數(shù)據(jù)序列化的過程中,已經(jīng)記錄了數(shù)據(jù)的位置和偏移量。這也是序列化后的數(shù)據(jù)要略大于 pb 的原因。

FlatBuffers 反序列化的過程就很簡(jiǎn)單了。由于序列化的時(shí)候保存好了各個(gè)字段的 offset,反序列化的過程其實(shí)就是把數(shù)據(jù)從指定的 offset 中讀取出來。

整個(gè)反序列化的過程零拷貝,不消耗占用任何內(nèi)存資源。并且 FlatBuffers 可以讀取任意字段,而不是像 Json 和 Protobuf需要讀取整個(gè)對(duì)象以后才能獲取某個(gè)字段。FlatBuffers 的主要優(yōu)勢(shì)就在反序列化這里了。所以 FlatBuffers可以做到解碼速度極快,或者說無需解碼直接讀取。

總結(jié)

FlatBuffers 和 Protobuf 一樣具有數(shù)據(jù)不可讀性,必須進(jìn)行數(shù)據(jù)解析后才能可視化數(shù)據(jù)。但是相比其它的序列化工具,F(xiàn)latBuffers最大的優(yōu)勢(shì)是反序列化速度極快,或者說無需解碼。如果使用場(chǎng)景是需要經(jīng)常解碼序列化的數(shù)據(jù),則有可能從 FlatBuffers 的特性中獲得巨大收益。

責(zé)任編輯:趙寧寧 來源: 云原生技術(shù)愛好者社區(qū)
相關(guān)推薦

2022-08-06 08:41:18

序列化反序列化Hessian

2011-06-01 15:05:02

序列化反序列化

2009-08-24 17:14:08

C#序列化

2023-12-13 13:49:52

Python序列化模塊

2009-08-06 11:16:25

C#序列化和反序列化

2011-05-18 15:20:13

XML

2018-03-19 10:20:23

Java序列化反序列化

2012-06-13 09:35:41

存儲(chǔ)虛擬化

2011-06-01 14:50:48

2009-06-14 22:01:27

Java對(duì)象序列化反序列化

2019-11-20 10:07:23

web安全PHP序列化反序列化

2009-08-25 14:24:36

C#序列化和反序列化

2016-09-21 00:15:27

2016-01-05 15:10:59

2021-11-18 07:39:41

Json 序列化Vue

2009-09-09 16:10:11

.NET序列化和反序列

2012-04-13 10:45:59

XML

2009-08-25 14:43:26

C#序列化和反序列化

2021-10-20 07:18:50

Java 序列化漏洞

2009-09-09 14:45:41

XML序列化和反序列化
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)