crowdedjs / examples

A threaded, browser-based crowd simulation engine.
https://crowdedjs.github.io/examples/
MIT License
2 stars 3 forks source link

Let the simulation run for a virtual day #67

Open rnarducci opened 3 years ago

rnarducci commented 3 years ago

image

It looks like as is, the simulation can run to completion. It does take a while though, somewhere around an hour to complete. It also gets slower as time goes on, around the 19 'hour' mark, it looked like 15 seconds in real life was 6 'minutes' in the simulation, whereas when it started it was less than a second per minute in the simulation.

bricksphd commented 3 years ago

Great news. That sounds like I'm doing something that doesn't allow for garbage collection. I'll look into it.

bricksphd commented 3 years ago

After digging and profiling, the slow down looks like it's related to two problems. I'll discuss one here and open another issue for the second one, #69

We have a lot of O(n) operations that turn into O(n^2) when used by many of our agents. The original code is all mine, so this isn't a personal critique, it's just time to start caching data or improving our algorithms so they stay in the O(1) range.

For example, in the LookForPatient behavior, it tries to find a reference to itself on every behavior tick.: https://github.com/crowdedjs/examples/blob/0fea4001d99c3e1e41659ca0714010e40cda8e37/src/behavior/look-for-arriving-patient.js#L21

This value can be cached, since we only need to find it during the first run of the behavior.

The real slow down comes when we iterate through all agents to get the kind of patient we are looking for, for example: https://github.com/bricksphd/trash.recast-detour/blob/e9100c3f542e19f75c0314b82866d688d1d43157/src/behavior/look-for-arriving-patient.js#L24

That particular line can run faster if we move the distance requirement on: https://github.com/bricksphd/trash.recast-detour/blob/e9100c3f542e19f75c0314b82866d688d1d43157/src/behavior/look-for-arriving-patient.js#L30

Into the search itself, i.e. ...&& Vector3.fromObject(a.location).distanceToSquared(myLocation) <= 3**2

...even better, we could have a global list in the Hospital object that maintains a list of patients that could be looked for, removing this expensive operation