Unity Tolua 性能优化(一)减少不必要的c#交互
最近使用的是unity+tolua,由于项目需求和性能改进,后面已经做过大量的修改,本文记录一些优化的地方
tolua是c#生成wrap导出接口给lua使用,在ObjectTranslator中通过一个Dictionary保存lua中引用c#的对象,保证该对象不会被回收,lua需要使用的时候也可以通过id获取该对象。
下面是平时使用时候一个很常见的代码:
代码1
self.goHead = self.gameObject.transform:Find("GoHead").gameObject;
这段代码功能很简单获取当前GameObject下子结点GoHead的GameObject.
下面看看这段代码与c#交互的过程。
先是self.gameObject.transform,在lua里面访问了gameobject的transform属性 我们看看UnityEngine_GameObjectWrap.cs具体执行了哪些操作
//UnityEngine_GameObjectWrap.cs
static int get_transform(IntPtr L)
{
object o = null;
o = ToLua.ToObject(L, 1);
UnityEngine.GameObject obj = (UnityEngine.GameObject)o;
UnityEngine.Transform ret = obj.transform;
ToLua.Push(L, ret);
return 1;
}
//ToLua.cs
public static void Push(IntPtr L, UnityEngine.Object obj)
{
PushUserObject(L, obj);
}
//ToLua.cs
static void PushUserObject(IntPtr L, object o)
{
Type type = o.GetType();
int reference = LuaStatic.GetMetaReference(L, type);
PushUserData(L, o, reference);
}
//ToLua.cs
public static void PushUserData(IntPtr L, object o, int reference)
{
int index;
ObjectTranslator translator = ObjectTranslator.Get(L);
index = translator.AddObject(o);
LuaDLL.tolua_pushnewudata(L, reference, index);
}
上面代码取了主要的流程,删除了一些跟问题无关的代码。
可以看到lua通过gameboject访问transform最终调用translator.AddObject(o); 把transfrom增加到lua对c#的引用字典里面进去。Find返回的子节点的transform也是一样的情况。这两个transfrom在这里我们并不需要,在下一次gc的时候就会被回收掉,明显是不必要开销。
解决这个问题也很简单减少lua对c#的调用就可以了,看下面代码:
代码2
//LuaUtil.cs
static public GameObject GetGameObject(GameObject goRoot, string path=null)
{
return goRoot.transform.Find(path).gameObject;
}
self.goHead = LuaUtil.GetGameObject(self.gameObject, "GoHead");
这里我们增加了一个c#的函数把结果直接返回,避免了lua访问不必要transfrom。
优化性能测试:
测试代码1
function LuaUtilTest.DoTest(goTest)
local tmStart = os.clock();
local testCount = 1000000;
local goTmp;
for __idx=1,testCount do
goTmp = goTest.transform:Find("GoHead").gameObject;
end
print("LuaUtilTest cost:", uiButton, os.clock()-tmStart);
end
测试代码2
function LuaUtilTest.DoTest(goTest)
local tmStart = os.clock();
local testCount = 1000000;
local goTmp;
for __idx=1,testCount do
goTmp = LuaUtil.GetGameObject(goTest, "GoHead");
end
print("LuaUtilTest cost:", uiButton, os.clock()-tmStart);
end
在unity2018.3 Windows10平台下 分别执行了100万次结果
| 测试代码 | 第一次 | 第二次 | 第三次 |
|---|---|---|---|
| 测试代码1 | 1.928s | 1.928s | 1.928s |
| 测试代码2 | 0.884s | 0.855s | 0.900s |
测试结果可以看到性能提升还是很明显的测试代码2执行时间不到测试代码2的一半
浙公网安备 33010602011771号