Unity DOTS系列之托管/非托管Component的区别与性能分析

2023-11-02 05:28

本文主要是介绍Unity DOTS系列之托管/非托管Component的区别与性能分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近DOTS发布了正式的版本, 我们来分享一下DOTS里面托管与非托管Component的区别与性能分析,方便大家上手学习掌握Unity DOTS开发。托管与非托管的区别在于是不是基于自动垃圾回收的。托管是由垃圾回收器来负责自动回收,非托管需要我们手动来做相关内存管理,不被垃圾回收系统来处理。

对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白,也有一些正在从事游戏开发的技术大佬,欢迎你来交流学习。

Unmanaged Component(非托管)

先来看下Unmanaged Component,它是我们在DOTS开发中使用最多的,性能最好的Component的类型。它的数据成员的类型会有一些限制:

  1. Blittable types: 这些类型可以在托管与非托管都有通用的表现形势,不需要额外的转换,如System.Byte,System.Int32等,具体可以参考Blittable types的详细解释(https://learn.microsoft.com/en-us/dotnet/framework/interop/blittable-and-non-blittable-types);
  2. bool与char类型;
  3. BlobAssetReference类型:Blob asset 的对象的引用;
  4. Collections.FixedString类型: 一个固定大小的character buffer;
  5. Collections.FilxedList 类型: 一个固定大小的List;
  6. FixedArray类型: 固定大小的一个数组类型,只能在unsafe环境中使用;
  7. 数据成员满足上面类型条件的其它结构体,

创建一个Unmanaged Component除了有上面数据成员类型的限制以外,你还要定义一个struct继承自 IComponentData。代码如下:

 public struct ExampleChunkComponent : IComponentData{public int Value;}

如果你定义了一个struct 继承自 IComponentData 但是里面没有加任何的数据,那么这种Component被称为Tag Component,在开发中用来做特定标记某些Entity。 Unmanaged Component的内存是基于ArchType分配在Chunk中的。它与所在Entity的其它Unmanaged Component基于ArchType排列在一起,这样可以获得很好的性能,因此Unmanaged Component在ECS开发中是最常用的一种组件数据类型。拥有很好的性能。

Managed Component(托管)

与Unmanaged Component相比,Managed Component可以使用任意类型的数据成员。但是在存储与访问中性能会不如Unmanaged Component。它更灵活方便,但是性能不及Unmanaged Component。同时它也由一些使用方面的限制:

  1. 不能够在jobs工作线程里面来使用Managed Component。
  2. 在使用Burst编译器编译的代码中不能使用Managed Component。
  3. 他们需要基于垃圾回收;
  4. 为了序列化,他们必须要定义一个没有参数的构造函数;

如果Managed Component中使用了托管的数据类型,可能需要手动添加序列化,Clone,比较等功能。定义一个Managed Component也非常简单,你只要定义一个class,继承自IComponentData,这样就定义好了一个Managed Component(注意非托管的是定义struct)。要么就不要构造函数,要么就定义一个没有参数的构造函数。参考代码如下:

 public class ExampleManagedComponent : IComponentData{public int Value;}

当我们的Managed Component引用了其它的一些引用而外资源的时候,我们最好实现ICloneable与IDisposable。例如,一个Managed Component有一个数据成员ParticleSystem,指向了一个粒子对象。当我们复制这个组件所在的Entity的时候。如果你实现了Icloneable,你就可以把这个ParticalSystem的引用复制给另外一个Component。如果你实现了IDisposable,这样你也可以基于这个机制来释放你的资源。

托管与非托管Component的性能比较

Managed Component的数据不直接存放在Chunk中,World会有一个很大的”数组”,专门来存放Managed Component,而我们Entity的基于ArchType的Component数据块中存放的是Managed Component的在数组中的偏移地址。这样当我们访问Managed Component的时候,需要查找,同时内存会跳开到别的地方,这样会导致Cache失效,所以性能会差一些。

Unmanaged Component的数据直接一起存放到Chunk中,这样访问的时候会非常高效,同时Cache命中率也会很高。同时UnmangedComponent可以直接在Burst Code中使用,能获得很好的执行性能。Unmanged Component的性能要比Managed Component的性能要好,这样大多数情况下我们尽可能用Unmanaged来代替Managed。

今天的 Managed Component 与Unmanged Component分析比较就到这里了,更多的DOTS系列,关注我们,持续更新!

这篇关于Unity DOTS系列之托管/非托管Component的区别与性能分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/328426

相关文章

C++ Sort函数使用场景分析

《C++Sort函数使用场景分析》sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使... 目录C++ Sort函数详解一、sort函数调用的两种方式二、sort函数使用场景三、sort函数排序

kotlin中const 和val的区别及使用场景分析

《kotlin中const和val的区别及使用场景分析》在Kotlin中,const和val都是用来声明常量的,但它们的使用场景和功能有所不同,下面给大家介绍kotlin中const和val的区别,... 目录kotlin中const 和val的区别1. val:2. const:二 代码示例1 Java

CSS Padding 和 Margin 区别全解析

《CSSPadding和Margin区别全解析》CSS中的padding和margin是两个非常基础且重要的属性,它们用于控制元素周围的空白区域,本文将详细介绍padding和... 目录css Padding 和 Margin 全解析1. Padding: 内边距2. Margin: 外边距3. Padd

Go标准库常见错误分析和解决办法

《Go标准库常见错误分析和解决办法》Go语言的标准库为开发者提供了丰富且高效的工具,涵盖了从网络编程到文件操作等各个方面,然而,标准库虽好,使用不当却可能适得其反,正所谓工欲善其事,必先利其器,本文将... 目录1. 使用了错误的time.Duration2. time.After导致的内存泄漏3. jsO

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法

SpringCloud动态配置注解@RefreshScope与@Component的深度解析

《SpringCloud动态配置注解@RefreshScope与@Component的深度解析》在现代微服务架构中,动态配置管理是一个关键需求,本文将为大家介绍SpringCloud中相关的注解@Re... 目录引言1. @RefreshScope 的作用与原理1.1 什么是 @RefreshScope1.

分辨率三兄弟LPI、DPI 和 PPI有什么区别? 搞清分辨率的那些事儿

《分辨率三兄弟LPI、DPI和PPI有什么区别?搞清分辨率的那些事儿》分辨率这个东西,真的是让人又爱又恨,为了搞清楚它,我可是翻阅了不少资料,最后发现“小7的背包”的解释最让我茅塞顿开,于是,我... 在谈到分辨率时,我们经常会遇到三个相似的缩写:PPI、DPI 和 LPI。虽然它们看起来差不多,但实际应用

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

Spring事务中@Transactional注解不生效的原因分析与解决

《Spring事务中@Transactional注解不生效的原因分析与解决》在Spring框架中,@Transactional注解是管理数据库事务的核心方式,本文将深入分析事务自调用的底层原理,解释为... 目录1. 引言2. 事务自调用问题重现2.1 示例代码2.2 问题现象3. 为什么事务自调用会失效3