mesa / mesa/mesa

Performance bottlenecks in mesa.discrete_space

Open
#3,379 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
3.9k
Forks
1.3k
Avg merge
2d 12h
Merged PRs (30d)
20

Description

**Summary**

While profiling mesa.discrete_space under a high-movement workload, I observed significant time spent in cell movement and occupancy checks. This issue summarizes the hotspots and proposes a few improvements.

**Reproduction**
````python
import random
import cProfile
from mesa import Model
from mesa.discrete_space.grid import OrthogonalVonNeumannGrid
from mesa.discrete_space.cell_agent import CellAgent

class DummyModel(Model):
pass

def run_benchmark():
model = DummyModel()
grid = OrthogonalVonNeumannGrid((100, 100), capacity=1)

agents = [CellAgent(model) for _ in range(5000)]

# initial placement
for agent in agents:
agent.cell = grid.select_random_empty_cell()

# random movement loop
for _ in range(500):
for agent in agents:
neighbors = agent.cell.neighborhood
target = random.choice(list(neighbors))
if target.is_empty:
agent.cell = target

if __name__ == "__main__":
cProfile.run("run_benchmark()", sort="cumtime")
````
**Observations**

- `Cell.is_empty` is called very frequently and currently computes `len(self._agents) == 0` every time.
- `CellAgent.cell` triggers add or remove operations that account for a large portion of total runtime.
- Neighborhood access wraps results in `CellCollection` and constructs intermediate mappings, contributing additional allocation overhead.

Total runtime is around 63 seconds
````
CellAgent.cell ~14.7s
Cell.is_empty ~11.1s
Cell.neighborhood ~6.8s
Cell.remove_agent ~6.1s
Cell.add_agent ~4.8s
````
**Proposed Improvements**

- Make `_empty` the single source of truth for emptiness and avoid recomputing `len(self._agents)` on every `is_empty` call.
- Reduce overhead in the movement pathnto avoid unnecessary repeated checks and work.
- Simplify how neighborhoods are constructed and returned to reduce intermediate allocations during frequent movement.

I plan to address these in separate PRs to keep changes focused and measurable.

Contributor guide

Open the contributing guide

Research direction

Start by running the provided cProfile benchmark, then inspect Cell.is_empty, CellAgent.cell, Cell.add_agent, Cell.remove_agent, and neighborhood access in mesa.discrete_space. Treat the proposed changes as separate, measurable efforts; done means reducing the identified hotspots without changing movement or occupancy behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
performance
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.