关于SLua的性能问题
Posted jianguhan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于SLua的性能问题相关的知识,希望对你有一定的参考价值。
最近在使用Slua,
这个玩意号称Fastest lua binding via static code generating,
然而在使用过程中发现效率低得吓人,
同样的功能如果用c++写会比这玩意快15倍,
虽然之前对在Unity里用lua会慢这事已经有心理准备了,
毕竟c#/c互调还是会有些消耗的,
而且Unity在编辑模式只能用debug编译,
速度可能会慢一些,
但是效率能差到这种程度着实出乎我的意料了,
翻了一下它的代码才发现,
这玩意的实现实在是一点都不fast啊。
先说c#导出到lua,最终会用这个函数注册到lua:
static public void pushcsfunction(IntPtr L, LuaCSFunction function)
LuaDLL.lua_getref(L, get(L).PCallCSFunctionRef);
LuaDLL.lua_pushcclosure(L, function, 0);
LuaDLL.lua_call(L, 1, 1);
来看一下PCallCSFunctionRef都干了啥:
local assert = assert
local function check(ok,...)
assert(ok, ...)
return ...
end
return function(cs_func)
return function(...)
return check(cs_func(...))
end
end
";
LuaDLL.lua_dostring(L, PCallCSFunction);
PCallCSFunctionRef = LuaDLL.luaL_ref(L, LuaIndexes.LUA_REGISTRYINDEX);
在这里把注册进去的函数包了一层,
所以在lua调一次函数实际上是调了三个函数,
这尼玛哪里fast了(一脸黑线)?
不知道为啥作者不搞成像tolua那样,
如果出错直接代码里报出来就可以了,
完全没必要搞成这样,
试了一下,
把LuaDLL.lua_getref(L, get(L).PCallCSFunctionRef)和LuaDLL.lua_call(L, 1, 1)干掉,
再简单修改一下LuaCodeGen.cs去掉push调用是否成功变量的代码以及去掉一些debug代码,
性能直接提升了差不多40%。
再来看c#调用lua函数,
流程上倒是没啥问题,
只是存在大量从c#调c的代码,
例如:
public bool pcall(int nArgs, int errfunc)
if (!state.isMainThread())
Logger.LogError("Can‘t call lua function in bg thread");
return false;
LuaDLL.lua_getref(L, valueref);
if (!LuaDLL.lua_isfunction(L, -1))
LuaDLL.lua_pop(L, 1);
throw new Exception("Call invalid function.");
LuaDLL.lua_insert(L, -nArgs - 1);
if (LuaDLL.lua_pcall(L, nArgs, -1, errfunc) != 0)
LuaDLL.lua_pop(L, 1);
return false;
return true;
其实可以把这个流程写在c那边,
只要导出一个函数给c#调就可以了,
完全不用调这么多次,
当调用次数变多时,
这里的开销就非常大了,
这个没有改代码测试了,
不过估计改完之后起码能提升20%~30%的性能吧
以上是关于关于SLua的性能问题的主要内容,如果未能解决你的问题,请参考以下文章