UH4L10——值类型绑定
UH4L10——值类型绑定
本章代码关键字
1 | appDomain.RegisterValueTypeBinder() //注册值类型与值类型绑定类的绑定,可以提高值类型计算效率 |
值类型绑定
通过上节课我们知道,CLR绑定其实就是把ILRuntime中用到的Unity相关方法
进行CLR重定向,让本来要使用反射去执行的一些逻辑变成直接执行,这样可以大大提升我们的性能
那么值类型绑定,其实就是把Unity当中的一些常用值类型方法进行CLR绑定,比如Vector2
、Vector3
、Quaternion
等
值类型绑定后,性能将得到大幅提升
值类型绑定,就是把Unity当中的一些常用值类型方法进行CLR绑定,它可以大幅提高在热更新工程中使用Unity中值类型对象的效率
如何进行值类型绑定
-
手写值类型绑定类(示例工程中提供了
Vector2
、Vector3
、Quaternion
的,可以直接使用)注意:手写值类型绑定类必须了解ILRuntime原理,详见:UH4L18——基本原理,UH4L21——重定向的书写规则
-
注册值类型绑定
appDomain.RegisterValueTypeBinder(typeof(值类型), new 绑定类());
,在CLR绑定脚本的InitILRuntime
中注册,1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public class ILRuntimeCLRBinding
{
static void InitILRuntime(ILRuntime.Runtime.Enviorment.AppDomain domain)
{
//这里需要注册所有热更DLL中用到的跨域继承Adapter,否则无法正确抓取引用
domain.RegisterCrossBindingAdaptor(new MonoBehaviourAdapter());
domain.RegisterCrossBindingAdaptor(new CoroutineAdapter());
domain.RegisterCrossBindingAdaptor(new TestClassBaseAdapter());
//需要在这里注册我们自定义的一些需要跨域继承的类
domain.RegisterCrossBindingAdaptor(new ILRuntimeAdapter.Lesson11_TestAdapter());
domain.RegisterValueTypeBinder(typeof(Vector3), new Vector3Binder());
domain.RegisterValueTypeBinder(typeof(Vector2), new Vector2Binder());
domain.RegisterValueTypeBinder(typeof(Quaternion), new QuaternionBinder());
}
}在运行时,在
appDomain
加载完热更新dll和pdb后也需要注册1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37//初始化ILRuntime相关的方法
private unsafe void InitILRuntime()
{
//注册委托和委托转换器
appDomain.DelegateManager.RegisterDelegateConvertor<MyUnityDel1>((action) =>
{
return new MyUnityDel1(() =>
{
((System.Action)action)();
});
});
appDomain.DelegateManager.RegisterMethodDelegate<int>();
appDomain.DelegateManager.RegisterFunctionDelegate<int, int, int>();
appDomain.DelegateManager.RegisterDelegateConvertor<MyUnityDel2>((func) =>
{
return new MyUnityDel2((i, j) =>
{
return ((System.Func<int, int, int>)func)(i, j);
});
});
//注册跨域继承类
appDomain.RegisterCrossBindingAdaptor(new ILRuntimeAdapter.Lesson11_TestAdapter());
//注册值类型
appDomain.RegisterValueTypeBinder(typeof(Vector3), new Vector3Binder());
appDomain.RegisterValueTypeBinder(typeof(Vector2), new Vector2Binder());
appDomain.RegisterValueTypeBinder(typeof(Quaternion), new QuaternionBinder());
//CLR重定向内容,必须要写到CLR绑定之前!!!
System.Type debugType = typeof(Debug);
MethodInfo methodInfo = debugType.GetMethod("Log", new System.Type[] { typeof(object) });
appDomain.RegisterCLRMethodRedirection(methodInfo, MyLog);
//注册 CLR绑定相关信息
ILRuntime.Runtime.Generated.CLRBindings.Initialize(appDomain);
//初始化ILRuntime相关信息(目前只需要告诉ILRuntime主线程的线程ID,主要目的是能够在Unity的Profiler剖析器窗口中分析问题)
appDomain.UnityMainThreadID = Thread.CurrentThread.ManagedThreadId;
}
性能优化体现
在ILRuntime热更工程中使用Unity中值类型进行计算,不进行值类型绑定的效率较低,进行值类型绑定后性能将大幅提升
热更新测试值类型计算测试代码:
1 | public class ILRuntimeMain |
假设不进行值类型绑定的注册(可以删掉所有值类型CLR绑定相关内容再测试(实际上如果删除值类型相关绑定内容,相比值类型计算消耗的时间,加载dll文件时速度会大幅度拖慢,值类型计算量越大,加载时间越长,原因不明)),直接计算,耗时如下:
然后进行值类型绑定的注册,直接计算,耗时如下:
1 | private unsafe void InitILRuntime() |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 文KRIFE齐的博客!