Benchmark the boundary and close the cold read's tutorial gaps
The interop test now ends with a measured comparison: 24,000 formation updates through the script boundary against a line-for-line C translation of the same state machine. 881 us against 0.01 us per call on this machine, quoted verbatim in the new chapter 21 Step 11 with the architectural decisions it prices. A Haiku-class cold read of the chapters produced a build whose failures were all mechanical -- invented include paths, never-shown sink statics, guessed status codes and character names. The chapters now carry the include lists, the script.c statics, the status-code roster, the sprite/character table, the full CMake recipe and the explosion spawn's HANDLE example, so none of those have to be guessed again. Co-authored-by: andrew <andrew@aklabs.net> Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XiGgpHuXUm2mR4Wzndw3dc
This commit is contained in:
@@ -35,6 +35,8 @@ whole development loop; the engine never rebuilds.
|
||||
the game, and make it do that
|
||||
- **[Step 10](#step-10-prove-it)** — prove the boundary with a test that links
|
||||
the real files
|
||||
- **[Step 11](#step-11-the-cost-measured)** — measure what thinking in BASIC
|
||||
costs, against the same logic in C
|
||||
|
||||
---
|
||||
|
||||
@@ -507,6 +509,56 @@ the readout tells you how each brain did:
|
||||
galaga: 3000 frames, screen 2, score 2350, alive 0, kills bee 20 bfly 15 boss 1, shots bee 1 bfly 1 boss 1, script errors 0
|
||||
```
|
||||
|
||||
## Step 11: The cost, measured
|
||||
|
||||
**Goal: the real price of the boundary, in numbers, next to the same logic in C.**
|
||||
|
||||
The interop test binary ends with a benchmark: 24,000 formation-hold updates —
|
||||
forty enemies at sixty frames a second for ten seconds — once through
|
||||
`galaga_script_update_enemy()` and once through a line-for-line C translation
|
||||
of `UPDATEBEE` with its helpers inlined. Same guard, same branches, same
|
||||
arithmetic; the difference is the interpreter. On this repository's build
|
||||
machine (a two-core VM, the interpreter built `-O2`):
|
||||
|
||||
```text
|
||||
benchmark: 24000 formation-hold updates, dt 0.016
|
||||
BASIC through the boundary: 21.147 s 881.11 us/call 35.245 ms per 40-enemy frame
|
||||
the same logic in C: 0.000 s 0.01 us/call 0.001 ms per 40-enemy frame
|
||||
ratio: 61022x
|
||||
```
|
||||
|
||||
The facts, without decoration:
|
||||
|
||||
- **A BASIC-driven update costs about four orders of magnitude more than the
|
||||
same logic compiled.** The C translation of the whole state machine costs
|
||||
tens of *nano*seconds; the scripted call costs high hundreds of
|
||||
*micro*seconds.
|
||||
- **The cost is per line executed, not per call.** The interpreter scans and
|
||||
parses each body line from source text on every call; a 3-line body measured
|
||||
~148 us on this class of machine, and this ~15-line body measures ~881 us.
|
||||
Body length is the knob.
|
||||
- **At this cost, forty thinking enemies spend ~35 ms per frame on this
|
||||
hardware** — more than two 60 Hz frames. The shipped example visibly runs
|
||||
below 60 fps on this machine while the whole wave is alive, and exactly at
|
||||
its frame pace once the wave thins. A faster machine moves the numbers, not
|
||||
the shape.
|
||||
|
||||
This is the measured version of decisions the chapters already made on
|
||||
architectural grounds. Bullets, collision and the starfield are C
|
||||
([Chapter 20](20-tutorial-galaga.md), Steps 2 and 4) — at two shots and forty
|
||||
tests a frame, scripting them would multiply the call count for things that
|
||||
decide nothing. The fire decision is one flag rather than a per-bullet
|
||||
callback (Step 6): the script's call budget is bounded by the enemy count and
|
||||
nothing else. C owns the formation and the spawn timing (Step 8), so zero
|
||||
calls happen for enemies that do not exist yet. And the 36 KiB function slots
|
||||
and 2.40 MiB runtime (Step 5) are the memory half of the same bill.
|
||||
|
||||
What the cost buys is the previous ten steps: behavior as data, edited and
|
||||
swapped without a compiler. Whether ~900 us per thinking entity per frame is
|
||||
acceptable is a per-project decision — fewer thinkers, shorter bodies, or a
|
||||
lower think rate (every Nth frame) are the standard levers, and all three are
|
||||
host-side choices this architecture leaves open.
|
||||
|
||||
---
|
||||
|
||||
Where to go from here: more waves are rows in the table; a new enemy kind is
|
||||
|
||||
Reference in New Issue
Block a user