Entitas
Entitas copied to clipboard
Using System.Stack slows down Entitas functions
Hi,
I've noticed a performance issue that arises due to using System.Stack<T>
in implementation of entitas.
Here is a screenshot from instruments that illustrates the problem:
As you can see Stack<T>
uses RuntimeHelpers.IsReferenceOrContainsReferences
function that takes 99% of its execution time (and in our case 2% of total frame time). As far as I can see its usage is an attempt to optimize method in case of using structs, but I think it does more harm than good in most cases(it is important to note that microsoft implementation does not use this or similar check)
Here is the code of Stack<T>.Pop()
from unity:
public T Pop()
{
int index = this._size - 1;
T[] array = this._array;
if ((uint) index >= (uint) array.Length)
this.ThrowForEmptyStack();
++this._version;
this._size = index;
T obj = array[index];
if (!RuntimeHelpers.IsReferenceOrContainsReferences<T>())
return obj;
array[index] = default (T);
return obj;
}
My suggestion would be to use either built-in or custom collection that doesn't implement such checks as it will greatly improve Entitas performance.
Are you using .Net 4.x?
Are you using .Net 4.x?
The instruments screenshot is made with project build with 2018.1.9 with .net 4.x backend
This one is made with 2018.3.4 with .net 4.x scripting backend
Did some research on why this method is even used in the Stack, it seems that this "optimization" is now included in dotnetcore and relies heavily on JIT compiler optimizing out this call. In ios UnityLand JIT is not a thing and it seems the proper way to address this issue is to get Unity to fix it.