几种常见的序列化方式简单使用及比较
## C++常见序列化方式
## json
* 测试
```
import json
def gen_json_inst():
inst = {
"f01": 0.1,
"f02": 0.1,
"f03": 1,
"f04": 1,
"f05": 1,
"f06": 1,
"f07": True,
"f08": "1",
"f09": "1",
"f10": {
"f11": ["1"]
},
}
return inst
def test_json():
inst = gen_json_inst()
data = json.dumps(inst)
t1 = int(time.time()*1000)
for i in range(100000):
encoded = json.dumps(inst)
json.loads(encoded)
t2 = int(time.time()*1000)
print("data len:%d, time elapsed:%dms" % (len(data), t2 - t1))
print(data)
```
* 结果
```
data len:124, time elapsed:1118ms
{"f01": 0.1, "f02": 0.1, "f03": 1, "f04": 1, "f05": 1, "f06": 1, "f07": true, "f08": "1", "f09": "1", "f10": {"f11": ["1"]}}
```
## protobuf
* 数据模板
```proto
// test.proto
syntax = "proto3";
message Other {
repeated string f11 = 1;
}
message SearchRequest {
float f01 = 1;
double f02 = 2;
int32 f03 = 3;
int64 f04 = 4;
uint32 f05 = 5;
uint64 f06 = 6;
bool f07 = 13;
string f08 = 14;
bytes f09 = 15;
Other f10 = 16;
}
```
```shell
protoc test.proto --python_out=. # 编译生成test_pb2.py
```
* 测试
```python
import time
from google.protobuf.json_format import Parse
import test_pb2
def gen_pb_inst():
inst = test_pb2.SearchRequest()
inst.f01 = 0.1
inst.f02 = 0.1
inst.f03 = 1
inst.f04 = 1
inst.f05 = 1
inst.f06 = 1
inst.f07 = True
inst.f08 = "1"
inst.f09 = b"1"
inst.f10.f11.append("1")
return inst
def test_pb():
inst = gen_pb_inst()
data = inst.SerializeToString()
t1 = int(time.time()*1000)
for i in range(100000):
encoded = inst.SerializeToString()
inst_1 = test_pb2.SearchRequest()
inst_1.ParseFromString(encoded)
t2 = int(time.time()*1000)
print("data len:%d, time elapsed:%dms" % (len(data), t2 - t1))
print(data.hex())
```
* 结果
```
data len:36, time elapsed:498ms
0dcdcccc3d119a9999999999b93f180120012801300168017201317a01318201030a0131
```
## capnproto
* 数据模板
```capnp
# test.capnp
@0x9e391fc8f3af545d;
struct Other {
f11 @0:List(Text);
}
struct SearchRequest {
f01 @0:Float32;
f02 @1:Float64;
f03 @2:Int32;
f04 @3:Int64;
f05 @4:UInt32;
f06 @5:UInt64;
f07 @6:Bool;
f08 @7:Text;
f09 @8:Data;
f10 @9:Other;
}
```
* 测试
```python
import capnp
capnp.remove_import_hook()
def gen_capnp_inst():
test_capnp = capnp.load("test.capnp")
inst = test_capnp.SearchRequest.new_message()
inst.f01 = 0.1
inst.f02 = 0.1
inst.f03 = 1
inst.f04 = 1
inst.f05 = 1
inst.f06 = 1
inst.f07 = True
inst.f08 = "1"
inst.f09 = b"1"
inst.f10.f11 = ["1"]
return inst
def test_capnp():
test_capnp = capnp.load("test.capnp")
inst = gen_capnp_inst()
data = inst.to_bytes_packed()
t1 = int(time.time()*1000)
for i in range(100000):
encoded = inst.to_bytes_packed()
out = test_capnp.SearchRequest.from_bytes_packed(encoded)
t2 = int(time.time()*1000)
print("data len:%d, time elapsed:%dms" % (len(data), t2 - t1))
print(data.hex())
```
* 结果
```
data len:49, time elapsed:250ms
100e5005031fcdcccc3d01ff9a9999999999b93f000101110101010111091211090a4108010131013111010e1101120131
```
## msgpack
* 测试
```python
import msgpack
def gen_msgpack_inst():
inst = {
"f01": 0.1,
"f02": 0.1,
"f03": 1,
"f04": 1,
"f05": 1,
"f06": 1,
"f07": True,
"f08": "1",
"f09": "1",
"f10": {
"f11": ["1"]
},
}
return inst
def test_msgpack():
inst = gen_msgpack_inst()
data = msgpack.dumps(inst)
t1 = int(time.time()*1000)
for i in range(100000):
encoded = msgpack.dumps(inst)
msgpack.loads(encoded)
t2 = int(time.time()*1000)
print("data len:%d, time elapsed:%dms" % (len(data), t2 - t1))
print(data.hex())
```
* 结果
```
data len:76, time elapsed:354ms
8aa3663031cb3fb999999999999aa3663032cb3fb999999999999aa366303301a366303401a366303501a366303601a3663037c3a3663038a131a3663039a131a366313081a366313191a131
```
## flatbuffers
* 数据模板
```fbs
// test.fbs
table Other {
f11:;
}
table SearchRequest {
f01:float;
f02:double;
f03:int;
f04:long;
f05:uint;
f06:ulong;
f07:bool;
f08:string;
f09:;
f10:Other;
}
```
```shell
flatc -p test.fbs # 生成Other.py SearchRequest.py
```
* 开发
```
import flatbuffers
import SearchRequest, Other
def dump_flatbuf_inst(inst):
f08_val = inst.CreateString("1")
f11_0_val = inst.CreateString("1")
SearchRequest.StartF09Vector(inst, 1)
inst.PrependByte(ord('1'))
f09_val = inst.EndVector()
Other.StartF11Vector(inst, 1)
inst.PrependUOffsetTRelative(f11_0_val)
f11_val = inst.EndVector()
Other.Start(inst)
Other.AddF11(inst, f11_val)
f10_val = Other.End(inst)
inst_inst = flatbuffers.Builder(0)
SearchRequest.Start(inst)
SearchRequest.AddF01(inst, 0.1)
SearchRequest.AddF02(inst, 0.1)
SearchRequest.AddF03(inst, 1)
SearchRequest.AddF04(inst, 1)
SearchRequest.AddF05(inst, 1)
SearchRequest.AddF06(inst, 1)
SearchRequest.AddF07(inst, True)
SearchRequest.AddF08(inst, f08_val)
SearchRequest.AddF09(inst, f09_val)
SearchRequest.AddF10(inst, f10_val)
end = SearchRequest.End(inst)
inst.Finish(end)
return inst.Bytes, inst.Head()
def test_flatbuf():
inst = flatbuffers.Builder(0)
data, l = dump_flatbuf_inst(inst)
t1 = int(time.time()*1000)
for i in range(10000):
encode, l = dump_flatbuf_inst(inst)
out = SearchRequest.SearchRequest.GetRootAs(encode, l)
t2 = int(time.time()*1000)
print("data len:%d, time elapsed:%dms" % (len(data), t2 - t1))
print(data.hex())
```
* 结果
```
由于flatbuf目前没有优秀的python wrapper,都是使用python模拟底层实现,因此效率极低,这里不做展示.
flatbuf效率应该高于上述几种方式,但是操作起来较复杂
```
## 性能对比
|prop |json |protobuf|flatbuf |capnproto |msgpack |
|----------|----------|----------|----------|----------|----------|
|speed(ms) |1118 |498 |- |250 |354 |
|size |124 |36 |256 |49 |76 |
页:
[1]