XLua 避免反射带来的GC 和耗时 优化

xlua 原理就是通过生成wrap代码,在运行时调用。
但在实际调试过程中,还是会有很多的反射代码被生成。
因此添加一个日志输出,可以看到哪些类型是没有被生成wrap,而lua中又用到了。

        public bool TryDelayWrapLoader(RealStatePtr L, Type type)
        {
            if (loaded_types.ContainsKey(type)) return true;
            loaded_types.Add(type, true);

            LuaAPI.luaL_newmetatable(L, type.FullName); //先建一个metatable,因为加载过程可能会需要用到
            LuaAPI.lua_pop(L, 1);

            Action loader;
            int top = LuaAPI.lua_gettop(L);
            if (delayWrap.TryGetValue(type, out loader))
            {
                delayWrap.Remove(type);
                loader(L);
            }
            else
            {
#if !GEN_CODE_MINIMIZE && !ENABLE_IL2CPP && (UNITY_EDITOR || XLUA_GENERAL) && !FORCE_REFLECTION && !NET_STANDARD_2_0
                if (!DelegateBridge.Gen_Flag && !type.IsEnum() && !typeof(Delegate).IsAssignableFrom(type) && Utils.IsPublic(type))
                {
                    Type wrap = ce.EmitTypeWrap(type);
                    MethodInfo method = wrap.GetMethod("__Register", BindingFlags.Static | BindingFlags.Public);
                    method.Invoke(null, new object[] { L });
                }
                else
                {
                    // 此处添加日志输出,可以看到在生成wrap代码后,还有哪些type在被反射生成
                    Debug.Log("jayden:ObjectTranslator.TryDelayWrapLoader:" + type + "");
                    Utils.ReflectionWrap(L, type, privateAccessibleFlags.Contains(type));
                }
#else
                Utils.ReflectionWrap(L, type, privateAccessibleFlags.Contains(type));
#endif
  // 以下代码省略

通过日志可以总结出一些规律:

1.class 中又定义了class、enum等类型

这种写法,在xlua的配置中GenConfig,通过命名空间方法添加的列表中,是无法生成warp类的。

尽量拆分代码文件,且放在命名空间下,即符合编码规范,也能减少配置项。

2.自定义的delegate 委托

public delegate void OnMapChanged();
public OnMapChanged EventOnMapChanged;

如果没有添加到GenConfig 的委托列表中,那么也会在运行时被反射添加。

这种情况应该尽量使用Action,Func,这种会在生成代码的时候,被合并。

你可能感兴趣的:(XLua 避免反射带来的GC 和耗时 优化)