Skip to content

Precompute fast-path eligibility for gang processing#576

Open
chall37 wants to merge 3 commits into
gnachman:masterfrom
chall37:feat/fastpath_state_machine
Open

Precompute fast-path eligibility for gang processing#576
chall37 wants to merge 3 commits into
gnachman:masterfrom
chall37:feat/fastpath_state_machine

Conversation

@chall37
Copy link
Copy Markdown
Contributor

@chall37 chall37 commented Feb 11, 2026

Summary

  • Cache fast-path eligibility as a boolean ivar (_fastPathEligible) instead of evaluating ~11 conditions on every gang processing call
  • Invalidate the cache at each state-mutation point (mode changes, trigger updates, expectations, print buffer, etc.) with self-healing recompute for lazy expectation expiry
  • Debug assertions validate cache consistency on every gang call
  • 14 tests cover all invalidation paths
  • Performance benchmarks for gang processing throughput

10 XCTest measure iterations x100 gang calls of 100 lines (10,000 lines per iteration, 1,000,000 lines total per test).

Branch Time
Master (inline checks) 44.774s
Fastpath (cached boolean) 3.679s

Replace the 11-condition runtime check in terminalAppendMixedAsciiGang:
with a precomputed _fastPathEligible ivar that is recomputed at each
state-mutation point. The hot path is now one ivar read plus two
lightweight checks (tokens.count and grid canTakeFastPath).

Add terminalActiveCharsetDidChangeTo: delegate callback so charset
changes (SI/SO) can invalidate the cache. Include a debug assertion
that validates the cached value against a fresh computation on every
call.
Address three cache invalidation bugs in the precomputed
_fastPathEligible boolean:

- Recompute after evaluateTriggers: block executes (expectations
  can be consumed by matching during trigger evaluation)
- Recompute after updateExpectFrom: updates expectations
- Recompute after setTerminalEnabled: assigns terminal modes
  during session startup/revive

Add self-healing recompute at the top of
terminalAppendMixedAsciiGang: for lazy expectation deadline
expiry (deadlines pass without notification, so the cache
cannot be eagerly invalidated).

Add mutation-queue-only annotations to _computeFastPathEligible
and _recomputeFastPathEligible.

Add 14 new tests covering every _fastPathEligible condition:
insert mode, wraparound, ANSI mode, alt buffer, command start
coord, line drawing mode, logging, publishing, expectations,
print buffer, multiple simultaneous conditions, expectation
consumed by match, expectation expired by deadline, and
post-trigger action drain transitions.
Add testGang_fastPathPerformance (cached boolean gang path) and
testGang_charAtATimePerformance (character-at-a-time baseline)
using XCTest measure blocks. 100 gang calls of 100 lines each
per iteration.
@chall37 chall37 marked this pull request as ready for review February 11, 2026 18:55
@gnachman
Copy link
Copy Markdown
Owner

I'm not sure the juice is worth the squeeze. After running it in an optimized build, I get:

  │              Test               │ Conditional (baseline) │ Unconditional │ Delta │
  ├─────────────────────────────────┼────────────────────────┼───────────────┼───────┤
  │ testGang_fastPathPerformance    │ 0.323s                 │ 0.321s        │ -0.6% │
  ├─────────────────────────────────┼────────────────────────┼───────────────┼───────┤
  │ testGang_charAtATimePerformance │ 2.091s                 │ 2.051s        │ -1.9% │
  └─────────────────────────────────┴────────────────────────┴───────────────┴───────┘

I've pushed my changes to the fastpath-perf branch so you can see what I did.

That being said, I do plan to merge the performance tests because it's awesome to have performance tests.

@chall37
Copy link
Copy Markdown
Contributor Author

chall37 commented Feb 13, 2026

Ah, I must have been benching the debug build! If the gains seem too good to be true...

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.

2 participants