【优化】Messages of Monobehaviour
本文目录 7 个章节
【优化】Messages of Monobehaviour
创建时间:2021/1/26 15:22
- 【优化】Messages of Monobehaviour
- 对”Magic Methods”原理的理解
- Unity官方文档中的解释
- 其他博主的理解
- Cost of magic methods
- 优化方案:Update Manager
- Experimentation
- Ref
- 对”Magic Methods”原理的理解
对”Magic Methods”原理的理解
Unity官方文档中的解释
Internally, Unity tracks lists of objects interested in its callbacks, such as Update, FixedUpdate and LateUpdate. These are maintained as intrusively-linked lists to ensure that list updates occur in constant time. MonoBehaviours are added to/removed from these lists when they are Enabled or Disabled, respectively. via. https://docs.unity3d.com/Manual/BestPracticeUnderstandingPerformanceInUnity8.html
其他博主的理解
‘Magic Methods’ are all the methods inherited from MonoBehaviour such as Awake(), Start(), Update(), FixedUpdate(), etc… When a MonoBehaviour is accessed for the first time, it is then scanned by the Common Language Runtime (CLR) for any ‘Magic Methods’ it may have in it. When the MonoBehaviour is scanned, all the ‘Magic Methods’ within it are then added to lists i.e. a list of Update() methods, a list of Start() methods, etc. Then when Unity calls these functions it simply iterates through the list of methods. via. https://creaturesurvive.github.io/repo/blog/unity-update-manager/
Unity doesn’t use System.Reflection to find a magic method every time it needs to call one. Instead, the first time a MonoBehaviour of a given type is accessed the underlying script is inspected through scripting runtime (either Mono or IL2CPP) whether it has any magic methods defined and this information is cached. If a MonoBehaviour has a specific method it is added to a proper list. During the game Unity just iterates through these lists and executes methods from it. via. https://blogs.unity3d.com/cn/2015/12/23/1k-update-calls/
Cost of magic methods
- They are calls from native C++ land to managed C# land. There is a small but significant overhead to invoking managed-code callbacks from native code
All of our C# scripts that we create inside Unity are compiled into Managed Code, managed code is code that is read and interpreted by the CLR. whereas Unity is made up of C++ that is compiled into Native Code, native code is code that is read and interpreted directly by the computer making it really fast. So here is the problem with this, Unity handles executing all of the magic methods from within the engine meaning its handled in Native Code, however the methods it is executing are contained in the Managed Code. Every time a method is executed from native to managed it generates overhead.
- Unity carries out a number of safety checks before calling these functions. The safety checks ensure that the GameObject is in a valid state, hasn’t been destroyed, and so on.
优化方案:Update Manager
An update manager is a class that holds a reference to all of your MonoBehaviour’s and executes all of their Update() methods each frame.
An Update Manager works the exact same way as unity handles its ‘Magic Methods’, it simply has a list of all the methods and executes them as needed. However there is one key difference, It’s all handled in Managed Code, so instead of suffering the same overhead as the unity implementation on a per call basis, it only generates overhead once.
Experimentation
Example: 10000 MonoBehaviours are created with this code inside:
string s1 = "Hello ";
string s2 = s1;
s1 += "World";
System.Console.WriteLine(s2);
//Output: Hello
10000 MonoBehaviours are created but instead of having an Update they have a custom UpdateMe method which is called by a manager script every frame like so:
string s1 = "Hello ";
string s2 = s1;
s1 += "World";
System.Console.WriteLine(s2);
//Output: Hello

当有大量的GameObjects执行Update逻辑时,自己写Manager,对这些Update逻辑进行管理,能节省CPU耗时。
Ref
https://blogs.unity3d.com/cn/2015/12/23/1k-update-calls/ https://creaturesurvive.github.io/repo/blog/unity-update-manager/