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,成本较高且不适合扩展。

posted @ 2023-04-24 20:06  mc宇少  阅读(104)  评论(0编辑  收藏  举报