« Proto Buffers in Lua | 返回首页 | 游戏资源的压缩、打包与补丁更新 »

继续完善 protobuf 库

又仔细推敲了两天,把 lua 版的 protobuf 库完善了一下。主要是做了两个工作:

  1. protobuf 本身的格式,google 是自描述的。定义为 google.protobuf.descriptor 。我先自己实现的 parser 图方便,用了自己的中间交换格式。为了日后更通用,稍微修改了一下,可以生成于官方相同的结构。解析的性能稍有下降,不过应该兼容性更好。

  2. 一开始实现的 api 虽然性能非常好。(经简单测试,是 python 库的 30~40 倍,和 C++ 库性能相当)但若消息格式复杂,实现起来稍有麻烦。所以我做了点小封装。即为每个消息生成一对函数,可以用来打包和解包完整的消息,映射到 lua 的 table 结构上。lua 生成代码供自己调用的技巧在 lua 社区广泛使用。比如 kepler 项目。这使得 lua 可以用很短的代码行数完成很复杂的工作,不失性能。我这个封装层只有 100 行代码左右,一大半代码是为了解决消息展开时有递归定义的情况,否则更简短。(message 中有一些 field 的类型是自己,这是一种不多见的用法,但 protobuf 似乎并没有拒绝这种用法)

在性能非常重要的场合,使用原始的 api 对简单的数据包处理,加上 lua-jit ,应该可以达到和 C 相近的性能。而另一些情况下,需要定义比较复杂的数据结构,并序列化。这个时候用封装过的 api 就好了。


这两天还有些想法。想做一个类似 rings 的多 state 库,和 rings 不同,我希望 states 间交换数据更为高效。

考察了一下 lua 的源代码,我觉得稍做改动就可以让多个 states 间共享一个 string table 。这样,states 间传递 string 就能从 O(n) 变为 O(1) 。

另外,借助 debug hook 和 coroutine 机制,可以让 lua 代码运行一小段片段后自动交回控制权。不过在不修改 lua 代码之前暂时还不能这么干。这是因为 yield 有一些限制。比较期待 lua 5.2 的发布,以后 yield 的限制会少很多。

使用多 states 对长期运行的服务器程序非常有帮助。可以回避许多不谨慎造成的内存泄露问题。

Comments

你好! 我公司项目打算用protobuf + lua 但貌似官方的只能支持lua5.1? 请问有办法让lua5.2用起来protobuf吗?
加上 lua-jit ,应该可以达到和 C 相近的性能 请问您这个结论是测出来的么 貌似实际测出来的情况不是这样子吧
做好了rings的替代库开源吧,这应该是个很实用的东西,期待

Post a comment

非这个主题相关的留言请到:留言本