Entitas icon indicating copy to clipboard operation
Entitas copied to clipboard

Question about performance

Open defik2944 opened this issue 6 years ago • 12 comments

Hi,

I have question about performance. I am realy begginer in programming but i try ur Entitas-CSharp and it feel realy, realy great. I saw ur videos 2015 and 2016 about it. And saw a few test in those videos. But i still have a question.

My project for now it some kind of evolution simulation. Where i have wolrd 150x150 where each cell is an object. Where we have many other objects (bush, seed, animal around 10000-20000 of each). And they all do very many actions each turn. All of that require a lot of performance.

And now close to my question. I saw https://www.youtube.com/watch?v=tGmnZdY5Y-E video and in https://youtu.be/tGmnZdY5Y-E?t=1094 Joachim Ante says about struct, iComponentData and memory reading. In my project where i must read a few arrays with 10000+ members in each memory reading can be a part of performance boost. In ur exeample https://github.com/sschmid/Entitas-CSharp/wiki/Unity-Tutorial-Hello-World we have one component:

using Entitas;

[Game]
public class DebugMessageComponent : IComponent 
{    
    public string message;
}

but he is a class. If we have array 20000 entity how they will be use a mamory? How fast reading will be? if we change it to:

using Entitas;

[Game]
public struct DebugMessageComponent : IComponent 
{    
    public string message;
}

it will be faster? (it work, i try to do that in example)


I am sorry if my question is stupid, and i am sorry for my poor english. But I will be very grateful for your reply.

with many thanks.

defik2944 avatar Jan 18 '18 14:01 defik2944

The entities are stored in a nice contiguous array so if the data on them are small they are very efficient to loop through. They are also pooled so there's very little performance hit or GC from creation and destruction. I think you should profile a quick mock-up of your actual application to see.

It might be slower than a pure C# approach where you write some manager class and store everything you need in an array you have complete control of, but what you lose there you massively gain in flexibility - Entitas is like an automatic manager for any kind of data in your game / simulation, so you can worry about what you do with the data rather than how you pass it around.

All in all it's probably something you'll have to see for yourself with a mock-up of the kind of task you want to perform.

There's been some discussion of structs vs classes as components - I'll let @sschmid discuss that though as he knows more than me.

FNGgames avatar Jan 18 '18 16:01 FNGgames

@defik2944 Unity's approach is different to the Entitas approach and for them it makes sense to use structs and not classes. Entitas is designed differently and classes are the better choice, please don't use structs as components. About a year ago I implemented another (private) ECS (called Eve) which is basically the same / similar that Unity does right now (struct arrays etc.) to evaluate Entitas performance. My result back then was that Entitas performance without reactice systems was on par and it was not worth it to drop Entitas in favour of Eve, because Entitas gave more flexibility and less restrictions at a comparable performance. Here's a performance test that I will share soon where x amount of cubes are rotated every frame. This particular image show Entitas without reactive systems, meaning you don't use e.ReplaceXyz but modify the component values directly. left: Unity with traditional monobehaviour right: Entitas

entitas-performance

Unity way memory: 28.7 MB Entitas way memory: 1.2 MB ~24x more memory

Having said that, if you're talking about 20000+ entities and each of them is doing sth each frame, I think there's no way around multithreading and parallelizing systems to achieve a decent performance. I recommend a sandboxed performance test to validate Entitas and if it fits your needs. Please make sure to disable VisualDebugging in the preferences and also use fast & unsafe when profiling! With 20000+ entities VisualDebugging will significantly drop performance in the Editor and you won't get accurate performance results!

sschmid avatar Jan 18 '18 19:01 sschmid

On the other hand, the amount of entities doesn't necessarily mean that you will end up with performance issues. I would be more interested in the amount of systems and if they will process all entities or just groups / subsets. Is it every frame or every turn?

sschmid avatar Jan 18 '18 19:01 sschmid

If it's possible for you to share more info I'm sure we can find a solution

sschmid avatar Jan 18 '18 19:01 sschmid

I try to describe. The first one - my turn is not equal to frame - cos of performance. I can reach only 4 turn in sec with a minimum 30 fps. How i am say i have field with 150*150 cells where each cell each turn do few actions: each cell have int water and each turn have "damage" on dis water. So simlpe: int MyWater - SunDmg. How i suppose it can be a first system who operated with 22500 array. The next one is a little more complex. Some type of cells (ground cells) haveMyWater more than 100. I have a function that distributes water to neighboring cells. With some descrise.

water

If to say otherwise i have WaterRelease() function who check all ground cells with water 100+ and release water in cells around.

I have array of Bush. Dis array can have maximum around 20000 members. Each turn each member must to do:

take some water from ground cells. take some sunenergy from sun (The same function as we used for the earth) do energy from two previous operation spend energy as cost of life each turn die if dont have energy if have enough energy use two most hardest function:

  1. calculate new henom for childred
  2. born children

it is only part for my Bushes and GroundCells. I have equal arrays for seeds and for animals. They do similar actions.

video: https://www.twitch.tv/videos/220116334

how it works:

all objects - ground cells, bushes and etc - scriptable objects, all functions works only with scriptable objects

i have two manager first one: create a two pool of scritable objects for each type of my "units". Pool of dead and pool of life. In start all objects in pool of dead. When we need a new one manager take one from dead and drop it in life. most part of funtions work only with life arrays. second one: create a two pool of game objects. visible object and not visible. each turn each scritable object chek - i am visible? if yes dis manager take one game object from invisible pool, drop it in visible, accociate it with dis scriptable object, ask scriptable object: who u are? how u look like? where u? and say all of that to game object. game object choose a sprite, choose a position and then is becoming visible.

its a main idea)

defik2944 avatar Jan 19 '18 12:01 defik2944

i think this could be done really efficiently in entitas. Mock something simple up, maybe even without the view layer, see how it runs for you

FNGgames avatar Jan 19 '18 13:01 FNGgames

okay :) i ll try to do it. thx for answers @FNGgames @sschmid

defik2944 avatar Jan 19 '18 19:01 defik2944

I'm making a similar game too. in my test, "replace component" takes time. 20000 plant entity get aged every 0.2sec, they replace age component(only have one float value). it takes 20ms. not slow, but 10times slower than just adding value 20000 float list. recommend run deep profiler first.

https://www.youtube.com/watch?v=h0uETw_XFn0

raveneer avatar Jan 20 '18 09:01 raveneer

Yes, if you're dealing with thousands of entities, you can get a massive performance boost by not using the replace method. Groups will still work, but reactive systems and EntityIndex only work in combination with the replace method

sschmid avatar Jan 21 '18 12:01 sschmid

Attempting to disable Visual Debugging results in Unity compiling for a second and then the option is re-enabled. I tried this as well with the generated and source folders empty in case things need to be re-generated before hand but same issue. I'm on version 46.3

owengalenjones avatar Jan 21 '18 17:01 owengalenjones

@owengalenjones This is fixed as of 0.47.3, see #540 for a workaround

sschmid avatar Jan 21 '18 18:01 sschmid

Is there any new performance test for latest version?

Zonciu avatar Mar 24 '19 06:03 Zonciu