I’m relatively new to ECS and wonder if it’s okay that every system I have allocates memory each frame. E.g. a very simple one for energy regeneration:
using Unity.Entities;
using UnityEngine;
public class EnergyRegenerationSystem : ComponentSystem {
protected override void OnUpdate() {
Entities.ForEach((ref EnergyData data) => {
if (data.CurrentEnergy >= data.MaxEnergy) return;
data.CurrentEnergy += data.RegenerationRate * Time.deltaTime;
if (data.CurrentEnergy <= data.MaxEnergy) return;
data.CurrentEnergy = data.MaxEnergy;
});
}
}
It seems when ForEach is executed a new NativeArray and underlying a new List ist created.
I’m using Unity 2019.2.17f1 on Windows with Entities 0.1.1.
Is this a bug, intention or am I just doing something wrong?
Unless I’m mistaken I think it’s from the lambda - the old ComponentSystem doesn’t do the compile time magic to avoid the GC allocations when using lambdas.
As a workaround im creating local function and put them in Delegates then pass the Delegates to the Entities.foreach which prevent the creation of GC on every frame. This is working for me.
Like Lucas said you should really just be using JobComponentSystem now, it lets you do the foreach lambda with no allocations and it will run faster than ComponentSystem even for main thread code. See the dots pong tutorial for an explanation.
Yes. In the latest version of Entities JobComponentSystem will run faster and avoid the allocation problems ComponentSystem has, so there’s no reason not to use it instead. I wouldn’t be surprised if ComponentSystem ends up being deprecated at some point. Just watch the video I provided in my previous post for a better explanation.
It’s already. Joachim mentioned that they will remove ComponentSystem and JobComponentSystem will be one full covering solution for main thread and jobified code.
Nice!! i didnt know about it. im going to watch it now
i like this way Unity’s is initiating it’s Community to ECS!
there is something im not understanding in this new way of writing Multithreaded Code by using the Entities.ForEach to replace the old way of doing things like ‘IJobParallelFor…’.
in the video he disabled the BurstCompile just because it’s using a static not ReadOnly variable inside the job. which is really a bad Approach, because Burst is amazingly optimizing performance even on main Thread.
in the old way it’s as simple as passing a copy of the value as readonly to the Job,but how to do this in the new ECS way of scripting ?
Basically you assign any outside data to a local variable just before you run the ForEach and then use that local variable in the ForEach as normal. If you need to it to be accessed as read only, you do
var something = Whatever
inputDeps = Entities.
WithReadOnly(something).
Foreach(...
The manual page for the new ForEach is actually surprisingly thorough and detailed. Highly recommended for learning the new syntax.