Skip to content

Make Units set operations linear instead of quadratic - #246

Open
JustinAWei wants to merge 1 commit into
BurnySc2:developfrom
JustinAWei:units-set-ops-linear
Open

JustinAWei wants to merge 1 commit into
BurnySc2:developfrom
JustinAWei:units-set-ops-linear

Conversation

@JustinAWei

Copy link
Copy Markdown

Units.__or__, __add__, __and__ and __sub__ check each unit's tag against a generator over the other collection:

other_unit.tag not in (self_unit.tag for self_unit in self)

That rescans the whole collection for every unit, so the cost is O(n·m). This PR collects the tags into a set once, so each check is O(1). The result is the same: same units, same order (self first, then the new units from other).

Why it matters

ares-sc2 merges its remembered (snapshot) units into the live unit lists every step:

self.ai.enemy_units = self.ai.enemy_units + memory_units
self.ai.all_enemy_units = self.ai.all_enemy_units + memory_units

Against a creep-heavy Zerg, all_enemy_units reaches several thousand entries (every creep tumor seen). In a profile of our bot against such an opponent, these merges were the largest single cost in ares' per-step update, about 2 ms per call. Together with other per-step work, that pushed the average step over the AI Arena 40 ms limit.

Benchmark

A plain CPython micro-benchmark of the + logic, run in this repo's uv env:

self + other before after
200 + 50 0.465 ms 0.011 ms
1000 + 200 8.45 ms 0.048 ms
3000 + 300 33.5 ms 0.115 ms

Tests

  • test_units gains assertions on all four operators that pin down deduplication and order.
  • uv run pytest test/test_pickled_data.py test/test_expiring_dict.py: 19 passed.
  • ruff check and ruff format --check are clean.

🤖 Generated with Claude Code

Units.__or__, __add__, __and__ and __sub__ checked each unit's tag against a
generator over the other collection, re-scanning it for every unit: O(n*m).
Collect the tags into a set once instead. Same units, same order.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@JustinAWei
JustinAWei marked this pull request as ready for review October 1, 2026 18:10
raspersc2 added a commit to august-k/python-sc2 that referenced this pull request Oct 2, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant