腾讯的热更新方案开源了

xLua是Unity3D下Lua编程解决方案,自2016年初推广以来,已经应用于十多款腾讯自研游戏,凭借其出色的性能,易用性,扩展性而广受好评。现在xLua开源到github上,希望能对游戏行业有所贡献。

xLua的几项突破

xLua在功能、性能、易用性都有不少突破,这几方面分别最具代表性的是:

1、Unity3D全平台热补丁技术,可以运行时把C#实现(方法,操作符,属性,事件,构造函数,析构函数,支持泛化)替换成lua实现;

2、自定义struct,枚举在Lua和C#间传递无C# gc alloc;

3、编辑器下无需生成代码,开发更轻量;;

初探xLua

xLua设计原则是保证了运行效率的前提下,尽量的保证开发效率。是不是简单易用,看了下面的例子你说了算,性能好不好,实际测试说了算。

三行代码跑lua脚本

一个完整的例子仅需3行代码:

下载xLua后解压到Unity工程Assets目录下,建一个MonoBehaviour拖到场景,在Start里头加上这么三行:

XLua.LuaEnv luaenv = new XLua.LuaEnv();

luaenv.DoString("CS.UnityEngine.Debug.Log('hello world')");

luaenv.Dispose();

运行就可以看到Console打印的hello world。

1、第一和第三行分别LuaEnv的创建以及销毁,所谓LuaEnv可以理解为lua虚拟机,往往整个工程一个虚拟机即可:

2、DoString里头可以是任意合法的lua代码,例子中调用了UnityEngine.Debug.Log接口打印了一个log(C#的静态函数在CS下直接可用);

C#调用lua系统函数math.max

xLua支持把一个Lua函数绑定到C# delegate。

我们先声明一个delegate,并为它加上CSharpCallLua标签:

[XLua.CSharpCallLua]

public delegate double LuaMax(double a, double b);

然后在上面那例子加上这么两行(luaenv销毁前):

var max = luaenv.Global.GetInPath<LuaMax>("math.max");

Debug.Log("max:" + max(32, 12));

就那么简单,把lua的math.max绑定到C#的max变量后,调用就和一个C#函数调用差不多了,而且,最最重要的是,执行了“XLua/Generate Code”后,max(32, 12)调用是不产生(C#)gc alloc的,既优雅,又高效!

更详细的可以看XLua\Doc下的文档。

热补丁技术

xLua支持热补丁,这意味着你可以:

1、开发只用C#;

2、运行也是C#,性能可以秒杀lua;

3、出问题了才用Lua来改掉C#出问题的部位,下次整体更新时换回正确的C#;能做到用户不重启程序fix bug;

把易用性进行到底

xLua的易用不仅仅体现在编程,还体现在方方面面的细节考虑,甚至考虑到团队配合工作流。

xLua菜单就两个,分别是生成代码和清除生成代码。

还能更简单些么?还能!上面两个菜单你开发期间甚至都不用管,要build手机版本前执行一下“Generate Code”就可以了(这也有API可集成到项目的自动化打包流程)。

这就是xLua的特色功能之一:编辑器下无需生成代码支持所有特性。

之所以做这个功能,是因为有的项目反馈,“生成代码”对于策划美术太高大上了一点,教了很久还是老忘;还有个大项目反馈说由于代码很多,每次生成代码后,Unity菊花都要转很久。。。

想项目所想,急项目所急本是我辈风范,就做了,尽管挺麻烦的。

无缝支持生成代码及反射

生成代码固然重要,已然是各大主流方案的标配。

反射有的方案明确不支持,但从项目的反馈来说,也是至关重要的:有的项目代码很多,已经接近苹果的80M Text段的限制,对他们来说,代码量大小关乎到能否发布,反射方式性能不如生成代码,但对安装包影响小。

这的无缝有两个含义:

1、两者在支持的特性以及特性的使用方式都是一致的,两者方式间切换,业务逻辑代码不用修改,改改配置就可以了;

2、两者无缝配合,比如一个继承链上,任意一个类都可以选择生成代码或者反射,比如子类选择生成代码,父类由于不常用选择了反射,还是可以在子类对象上调用父类的方法;

对于il2cpp的stripping,xLua也考虑到了,只要你对一个类配置了ReflectionUse,会自动生成Unity的link.xml配置文件,将该类型列为不剪裁。

关于性能

作为一个基础库,性能是至关重要的,其中又有一项指标是大家极为关注的:C#侧的gc alloc,xLua在这块做了不少创新。

正如前面例子所示,xLua支持把一个Lua函数绑定到一个C# delegate,这可以避免值类型在参数传递时产生的gc。

另外,在复杂值类型表达方面,xLua也取得相当突破。只要一个struct只包含值类型,配置了GCOptimize后,其参数传递,数组访问无gc。

所有枚举,配置了GCOptimize后无gc;

更多无GC的用法可以参见配套的例子(XLua\Examples\05_NoGc)。

不仅仅GC优化这块,Lua和C#间相互调用性能也可圈可点,具体可以关注我们发出的性能测试报告。

PS:我们的性能测试没有用网上流传较广的那套用例。我们认为其并不合理:

1、测试Lua调用C#部分用例选择了Vector3,这其实是错误的,市面上大多方案的Vector3是完全在Lua测重新实现,完全没有达到测试“Lua调用C#”的目的;

2、测试全部用Unity API做测试,这并不合理,Unity API本身的开销会影响到测试结果。举个例子:方案A的Lua调用C#函数开销是1ms,方案B是2ms,那么结论应该是A方案性能是B方案两倍,但如果被调用C#函数本身耗时100ms,那结论就是两个方案性能差不多,甚至有时会因为误差得出B方案性能更好的结论。

更合理的做法是用空负荷的类型(函数是空的,property,event等也不要有运算开销),xLua所有测试用例都是基于这个原则。

扩展性

开发中我们往往要用到很多东西,比如用PB和后台交互,解析json格式的配置文件等等。虽说我们都可以在C#那找到相应的库,然后通过xLua去使用这些库,但这效率不高,最好能有相应Lua的库。

不少方案是直接集成一些常用的Lua库,但这带来些新问题:

1、这些库不一定用到,却增大安装包;

2、集成的库也不一定符合项目习惯:json解析有人喜欢rapidjson,有人爱用cjson,所谓众口难调;

3、对于某些项目,这些库还是不够,还是得自己去想办法加;

我们的原则是授之以鱼,不如授之以渔,xLua在这方面的支持是:

1、提供了接口,教程,让大家可以不修改xLua代码就可以加入自己喜欢的库;

2、xLua用cmake实现跨平台编译,大家可以选择伴随xLua一起编译,修改一个makefile文件,搞定各平台编译。

除了很方便加入第三方Lua插件,xLua的生成引擎支持二次开发,可以编写生成插件,生成自己所需的一些代码,配置。

后续持续支持

用开源,最怕碰到情况是:作者已“死”,有事烧香。“死”主要是说不维护了,可能是作者太忙,或者没兴趣了,或者写着写着感觉进入一个死胡同,重构(做)了个完全不一样的版本,原来版本直接抛弃等等。

用xLua就没这方面的担心,大公司支持,开发,测试,答疑都有全职的团队。腾讯自己都有很多项目在使用呢。

版本开发流程很正规,较大版本会做一次主流机型的适配测试,用着就放心。

总结一下

xLua推广以来,用心倾听应用项目的需求,在易用性,性能,扩展性等方面得到长足的进步,开源后也将会继续秉承这个这原则,做一款有诚意的库。

本文介绍项目在github上的地址:

https://github.com/Tencent/xLua

原文发布于微信公众号 - 韩大(handa1740168)

原文发表时间:2017-01-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java3y

两个月的Java实习结束,继续努力

另外值得一说的是:别以为我写了那么多博客的就很厉害,很牛逼,其实我渣得一批!校招的算法笔试题基本没有ac的,在面试的时候,知识点说忘就忘。我写博客主要是记录一下...

681
来自专栏腾讯开源的专栏

手游热更新方案xLua开源:Unity3D下Lua编程解决方案

xLua是Unity3D下Lua编程解决方案,自2016年初推广以来,已经应用于十多款腾讯自研游戏,凭借其出色的性能,易用性,扩展性而广受好评。现在xLua开源...

5336
来自专栏ImportSource

使用DDD来构建你的REST API,而不是CRUD

? REST围绕着资源这个概念而构建的,然后用URI来表示。然后一个HTTP动词和资源URI组合起来对指定资源进行HTTP调用来执行操作。大多数REST框架提...

3125
来自专栏企鹅号快讯

SEO×静态、动态、伪静态URL的特性

1、静态页面 优点:相比其他两种页面,速度最快。不仅仅是秒杀秒客网加载速度最快,而且不需要从数据库里面提取数据,速度快的同时,也不会对服务器产生压力。 缺点:由...

1968
来自专栏Linyb极客之路

API设计:先思考再编码

793
来自专栏何俊林

美团猫眼电影Android模块化实战总结

首先一句话概括:我想把这几个月做的事情记录下来,并且希望尽量详细,希望读者读了这篇文章能够知道项目进行模块化,项目改业务框架可能会遇到哪些问题,具体每个步骤都做...

1192
来自专栏cloudskyme

众推平台架构——分布式爬虫

分布式爬虫架构 经过新一轮的投票,项目的范围已经基本确定。 ? 大家决定 全力以付,集中攻克“分布式爬虫”。 分布式爬虫架构1 使用队列,即生产者,消费都模式。...

3205
来自专栏葡萄城控件技术团队

全新的.NET解释器 - Mono已经到来

1164
来自专栏大数据

如何查询InfluxDB

InfluxDB是一个很流行的基于时间序列的数据库,下面是这个数据库的最基本的查询命令。InfluxDB使用类SQL(实际上它就是一种特殊的“SQL”)的语言。

79110
来自专栏算法+

c语言智能指针 附完整示例代码

资源获取即初始化 (Resource Acquisition Is Initialization, RAII),RAII是一种资源管理机制,资源的有效期与持有资...

1236

扫码关注云+社区