yuxiang-gao / PySocialForce

Extended Social Force Model in Python for social navigation research
MIT License
128 stars 36 forks source link

Fast obstacle force no refactoring #7

Closed Bonifatius94 closed 1 year ago

Bonifatius94 commented 1 year ago

Changes

I've used your visual tests to make sure the obstacle force works as expected. You can verify if you want @yuxiang-gao.

The former obstacle force code took 95% of 433s whereas the new implementation takes only 8% of 16.5s, so it's more than 300x faster according to my benchmark.py. But it could be even faster if we add mechanisms for pruning irrelevant forces of obstacles that are far away and therefore almost zero. There's still lots of room for further improvements. But for now, other forces are dominating the benchmark, so it doesn't make sense to optimize the obstacle force any further.

Additionally, there are a few more performance improvements concerning the social force / desired force, normalization of vectors into a list of (unit vector, length) tuples and a few other things concerning the Numba JIT optimizer. It's mostly related to reducing NumPy array allocations by allocating a results array ahead of time for cases where the array size is known upfront. Moreover, your former code had better vectorization at first glance, but somehow Numba seems to compile simple loops into faster code, so I tried to adopt this style of coding wherever it showed improvements.

So yeah, your overall performance improvements by merging my changes should be about 25x.

Benchmarks

This first benchmark shows the force computation which took 433 seconds and the obstacle force's footprint was 95%.

pysf-benchmark-slow-433-secs

This second benchmark shows the optimized force computation and stateutils taking 66% + 18% of 16.5 seconds. Another 5% of the remaining 16% of time is due to initialization efforts for loading packages like NumPy and matplotlib. Loading the config file is 1% and scene.py is 8.5%.

pysf-benchmark-fast-16-secs