Skip to content

[ports] Change input/output port declarations to class attributes - #511

Merged
sea-bass merged 1 commit into
develfrom
improve-ports-definitions
Aug 26, 2026
Merged

sea-bass merged 1 commit into
develfrom
improve-ports-definitions

Conversation

@sea-bass

@sea-bass sea-bass commented Aug 24, 2026 •

Copy link
Copy Markdown
Member

Breaking change, but a useful one, as it prevents the same dictionary from being recreated multiple times when calling input_ports() / output_ports().

Here's a quick Claude analysis:

I benchmarked the committed new code against its parent commit
(d85acf3, the classmethod version) on a node with two input ports
(one with a list[int] default) and one output port —
best of 5 runs of 50k iterations each:

  ┌────────────────────────────────┬──────────┬──────────┬─────────┐
  │     Operation (tick path)      │   Old    │   New    │ Speedup │
  ├────────────────────────────────┼──────────┼──────────┼─────────┤
  │ input_ports()                  │ 1,831 ns │ 22 ns    │ ~80x    │
  ├────────────────────────────────┼──────────┼──────────┼─────────┤
  │ get_input() — data present     │ 5,590 ns │ 1,933 ns │ ~2.9x   │
  ├────────────────────────────────┼──────────┼──────────┼─────────┤
  │ get_input() — default fallback │ 5,998 ns │ 2,325 ns │ ~2.6x   │
  ├────────────────────────────────┼──────────┼──────────┼─────────┤
  │ _set_output()                  │ 2,071 ns │ 1,178 ns │ ~1.8x   │
  ├────────────────────────────────┼──────────┼──────────┼─────────┤
  │ get_port_type()                │ 2,827 ns │ 150 ns   │ ~19x    │
  └────────────────────────────────┴──────────┴──────────┴─────────┘

  The headline: the per-tick operations every behaviour actually uses got 2–3x faster.

  There's also a small non-tick win: the input/output overlap check runs once per class at import instead of on every
  instantiation, so constructing many short-lived nodes (e.g. rebuilding subtrees) got marginally cheaper too.

and a bigger benchmark case:

● Here's the large-tree result — and it's more dramatic than the micro-benchmark suggested. Setup: 1,000 leaves (100
  sequences × 10 leaves), each declaring 7 input ports (5 wired to shared blackboard keys, plus a float and a list[int]
  default) and 4 output ports, all read and written on every tick — so 7,000 port reads and 4,000 writes per tree tick:

  ┌──────────────────────────────────────────────┬────────────────────────┬────────────────────────┬─────────────┐
  │                    Metric                    │   Old (classmethod)    │    New (attributes)    │ Improvement │
  ├──────────────────────────────────────────────┼────────────────────────┼────────────────────────┼─────────────┤
  │ Tick, whole tree                             │ 104.2 ms/tick (9.6 Hz) │ 23.9 ms/tick (41.9 Hz) │ 4.4x        │
  ├──────────────────────────────────────────────┼────────────────────────┼────────────────────────┼─────────────┤
  │ setup_ports(), all nodes                     │ 229.7 ms               │ 43.2 ms                │ 5.3x        │
  ├──────────────────────────────────────────────┼────────────────────────┼────────────────────────┼─────────────┤
  │ Instantiate 1,000 nodes                      │ 26.9 ms                │ 10.7 ms                │ 2.5x        │
  ├──────────────────────────────────────────────┼────────────────────────┼────────────────────────┼─────────────┤
  │ PortInformation objects constructed per tick │ 130,000                │ 0                      │ —           │
  └──────────────────────────────────────────────┴────────────────────────┴────────────────────────┴─────────────┘

... The practical framing: this tree couldn't tick at 10 Hz before, and comfortably ticks at 40 Hz now. Same tree, same
     behaviours, same blackboard — the entire difference is declaration rebuilding. Put differently, the old implementation
     was spending ~77% of every tick constructing and throwing away 130,000 frozen dataclasses (which is also pure
     allocator/GC churn, unpleasant for latency jitter in a robotics control loop).

@sea-bass
sea-bass marked this pull request as ready for review August 24, 2026 21:48
Base automatically changed from default-port-values to devel August 26, 2026 11:59
@sea-bass
sea-bass force-pushed the improve-ports-definitions branch from 18ecf1a to 53873cf Compare August 26, 2026 12:00
@sea-bass
sea-bass merged commit 1142b2d into devel Aug 26, 2026
4 checks passed
@sea-bass
sea-bass deleted the improve-ports-definitions branch August 26, 2026 12:01
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