继续完善 protobuf 库
又仔细推敲了两天,把 lua 版的 protobuf 库完善了一下。主要是做了两个工作:
protobuf 本身的格式,google 是自描述的。定义为 google.protobuf.descriptor 。我先自己实现的 parser 图方便,用了自己的中间交换格式。为了日后更通用,稍微修改了一下,可以生成于官方相同的结构。解析的性能稍有下降,不过应该兼容性更好。
一开始实现的 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
Posted by: 张生 | (3) October 20, 2014 11:19 AM
Posted by: mikebibi | (2) August 11, 2012 04:10 PM
Posted by: lichking | (1) August 18, 2010 07:02 PM