找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 9520|回复: 2

Google protobuf使用中的小陷阱

[复制链接]
发表于 2009-12-2 20:21:03 | 显示全部楼层 |阅读模式
在使用Protobuf中,发现对大数据包进行反序列化的的时候,
在数据包大于1m之后,随着数据包大小的线性增长,
反序列化的时间的增长幅度近乎斜率为2,这显然是难以忍受的。
下面是测试数据
500k 0.5s
1m  2.2s
2m 8s
3m 12s

于是在对Protobuf不断进行测试后发现,
在由于在被编译平proto文件中进行了类似如下设置如:
required string sname = 1 [default = "lily"];
required string sAddr= 2 [default = ""];
因此认为在对象构造的时候,sname字段将自动初始化为"lily",sAddr将自动初始化为"";
序列化与反序列放心的去使用通用的版本如ParseFromArray,
而非带有Partial字样的版本如ParsePartialFromArray。

后查看生成的代码发现实际上并不是这样,sname字段确实自动初始化为"lily",sAddr确没有被初始化。
因此在反序列化的时候由于检查字段缺失,会造成相当明显的时间损失。
经测试,即使近缺少这样一个字段的初始化,造成4-5倍的时间的损失是很平常的。
很不幸,我将这样的类定义在了一个list(repeated字段)里面,因此带来的时间损失更为严重。

测试手动对生成代码中未默认初始化的字段进行赋值,其他默认已经初始化的字段不做任何设置,
之后进行反序列化,下面是测试结果:
2M 0.32s
4m 0.65s
8m 1.2s
40m 7s
基本上反序列化的时间是随数据包增大程线性增长的,这是我们预期的结果。

结论,在编译proto的时候,如果string类型默认设置为"",一定要记得手动初始化。
目前使用版本为protoc-2.1.0-win32,也许接下来的版本会修正该bug。
发表于 2009-12-23 10:06:06 | 显示全部楼层
不错,学习了。。。。
发表于 2011-1-18 11:46:25 | 显示全部楼层
学习学习!
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-12-22 17:38 , Processed in 0.019520 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表