GCOptimize标签
原文:Unity中xLua与toLua对Vector3的优化 - 简书 (jianshu.com)
对C#纯值类型(包括struct,但struct只能包含值类型,或者C#的枚举)加上这个标签,会使得该类型在lua和c#间传递不产生GC,该类型的数组也不会产生GC。
原理:优化了值类型传递过程中的拆装箱操作
以Vector3为例:
lua中的存储方式
lua中有两种方式表示Vector3:
1.userdata(使用GCOptimize)
C#创建Vector3对象,调用 translator.PushUnityEngineVector3(L, __cl_gen_ret)(打了这个标签才生成,如果不想优化就不打标签,直接调用
PushUnityEngineVector3
做的优化是申请一块userdata(size=12),将Vector3拆成3个float,Pack到userdata,push到lua。这种userdata传回C#的时候有一个Pack对应的eUnPack过程。
正常的Push:public void Push(RealStatePtr L, object o),会发生一次装箱。
2.table:{x = 1,y = 2, z = 3}
创建时不予C#交互,传给C#后,在C#UnPack这个table,取出 xyz ,复制给new Vector3使用。
交互:
1.C#的Vector传给lua
最终会跑到C#的生成代码的get方法
translator.PushUnityEngineVector3(L, __cl_gen_to_be_invoked.position);//申请一块userdata(size=12),将Vector3拆成3个float,Pack到userdata,push到lua
2.lua的Vector传给C#
最终会跑到C#的生成代码的set方法
lua有两种写法:
1.aTransform.position = CS.UnityEngine.Vector3(7, 8, 9)
先获取userdata指针,在调用CopyByValue.UnPack
从指向内存的起始地址读取x,y,z值,设置到out UnityEngine.Vector3 field
CopyByValue.UnPack的实现:解userdata,与Pack对应:
2.aTransform.position = {x = 1, y = 2, z = 3}
直接调用 CopyByValue.UnPack
,将Table的x,y,z值取出,设置到out UnityEngine.Vector3 val
CopyByValue.UnPack的实现:直接从栈中读取三个float值:
toLua实现方式
用lua重新实现了Vector3,包含所有方法;与C#没有交互(更改不会同步)。
两种实现方式对比
1.都不会产生GC
2.tolua效率更高,xlua使用Vector3的时候需要与C#交互,tolua纯lua执行。
3.tolua需要lua重写一个Vector3,成本较高且不适合扩展。