Notifications
Article
在编辑器工具中快速提取类型属性
Published 25 days ago
116
0
如果你针对Unity 2019.2开发编辑器实用功能或资源包,可以使用UnityEditor.TypeCache API处理类型提取过程,以减少工具的初始化时间,进入运行模式的时间以及域重载的时间。

产生性能问题的原因

在调查和优化进入运行模式的过程时,我们发现从加载的程序集提取类型需要很长的时间。
类型提取在内部被编辑器模块广泛使用,在外部被资源包和用户代码用于扩展编辑功能。积累效果根据项目而不同,可能会给域重载时间增加300-600毫秒,如果系统具有延迟初始化,它会增加更多时间。
在新的Mono运行时中,由于Type.IsSubclassOf的性能下降问题,所需时间会大幅提升,最多可达1300毫秒。
产生性能问题的原因是,代码通常会从当前域提取所有类型,然后迭代所有类型,执行耗费性能的检查。所需时间会根据游戏拥有的类型数量而线性增加,通常游戏的类型数量为3~6万。

解决方法

缓存类型信息允许我们减少在域中迭代类型产生的O(N)复杂度。在本地层级,我们已经有了加速结构,它们会在程序集加载后填充,并缓存类型数据,例如:方法,类属性和接口实现。
在内部,这些结构会通过UnityEditor.EditorAssemblies API公开,以利用快速缓存功能。然而,该API并没有公开发布,而且也不支持重要的SubclassesOf用例。
在Unity 2019.2中,我们优化并扩展了本地缓存,并将其作为公开的UnityEditor.TypeCache API。它可以非常快速的提取信息,允许仅对我们感兴趣的少量类型进行迭代,一般为10-100个,这样可以显著降低编辑器工具获取类型所需的时间。
我们在本地拥有的基础数据由数组来表示,并且它对于域生命周期是不可改变的。因此,我们可以使用返回IList<T>接口的API,它会实现为本地Dynamic_array数据的视图,它会给我们提供:
  • IEnumerable(foreach和LINQ)的灵活性和可用性。
  • 使用for (int i)进行快速迭代
  • 快速转换为List<T>和Array

使用示例

下面查看几个示例。
通常,查找接口实现的代码如下:
通过TypeCache API,只需使用以下代码:
类似的,查找用属性标记的类型需要以下代码:
通过使用TypeCache API,只需要一行代码:

性能

如果我们使用性能测试框架编写简单的性能测试,我们可以清楚看到使用TypeCache API的优势。
在一个空白项目中,我们可以在域重载后节省超过100毫秒的时间。
未来在Unity 2019.3中,TypeCache.GetTypesDerivedFrom也支持把泛型类和接口作为参数。大部分编辑器代码已经转换为TypeCache API。
所以,我们希望用户尝试使用TypeCache API,你的反馈将帮助我们使编辑器变得更快。
如果你开发的编辑器实用功能或资源包需要扫描域中的所有类型,以使其变得可定制,请考虑使用UnityEditor.TypeCache API,使用它的积累效果会显著降低域重载时间。

小结

了解UnityEditor.TypeCache API:https://docs.unity3d.com/2019.2/Documentation/ScriptReference/TypeCache.html
更多Unity 2019.2新功能介绍,尽在Unity Connect平台(Connect.unity.com)。 观看部分Unity官方视频,请关注B站帐户:Unity官方。
Tags:
Unity China
610
Comments