Files
TerminalBasic/crates/tb-vm/benches/vm.rs
Chili Palmer f7e57b0bd8 Phase 2 abgeschlossen: Bytecode, TBVM, Runtime-Scheibe, tbc run
- Sema zum Lowering-Pass umgebaut: typisiertes HIR (Slots, explizite
  Konvertierungsknoten) als Codegen-Eingabe; BYREF verlangt exakten Typ
- Bytecode-Feindesign umgesetzt: monomorpher Opcode-Satz,
  .tbc-Container (Formatversion 1) mit eigenem Writer/Reader
- Codegenerator HIR -> Bytecode (Fixup-Listen, keine globalen Passes)
- TBVM-Interpreter: Kontrollfluss, GOSUB-Stack je Frame, BYREF/BYVAL,
  STATIC, DEF FN, DATA/READ/RESTORE, ON [LOCAL] ERROR/RESUME/ERR/ERL,
  Breakpoints/Einzelschritt/Inspektion, STOP fortsetzbar
- Runtime-Scheibe: Host-Trait (Konsole/Capture), Builtin-Tabelle,
  Konvertierungsmatrix, PRINT-Formatierung/Druckzonen, Stringfunktionen
- tbc run/build/check mit Exit-Codes nach Entscheidung D6
- Korpus-Harness (byte-genauer Vergleich) + 3 neue Korpusdateien
  (konvertierung, fehlerbehandlung, byref); 137 Tests gruen
- Benchmarks: Einzelmodul 1,2 ms / Projekt 49.760 Zeilen 124 ms
  (Budgets eingehalten), VM ~5 Mio Schleifeniterationen/s
- Doku fortgeschrieben (tbvm-design, sprachreferenz, PLAN);
  verlagerte Punkte als explizite Aufgaben in Phase 3
- OpenSpec-Change phase-2-bytecode-vm (27/27 Tasks)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-09-02 11:28:07 +02:00

58 lines
1.8 KiB
Rust

//! VM-Durchsatz-Benchmark (Messlatte docs/tbvm-design.md, „Performance"):
//! Schleifen- und String-Lasten. Eigener Harness; `cargo bench -p tb-vm`.
use std::time::Instant;
use tb_runtime::host::CaptureHost;
use tb_vm::interp::{RunEvent, Vm};
fn run_timed(name: &str, src: &str, work_units: f64, unit: &str) {
let module = tb_vm::compile_source("BENCH", src).expect("kompiliert");
let mut vm = Vm::new(module);
let mut host = CaptureHost::default();
let t = Instant::now();
let ev = vm.run(&mut host);
let secs = t.elapsed().as_secs_f64();
assert_eq!(ev, RunEvent::Ended, "{ev:?}");
println!(
" {name}: {:.0} ms ({:.1} Mio {unit}/s)",
secs * 1000.0,
work_units / secs / 1e6
);
}
fn main() {
println!("VM-Durchsatz-Benchmark (Release):");
// Ganzzahl-Schleife: 10 Mio Iterationen mit Arithmetik.
run_timed(
"INTEGER-Schleife (10 Mio)",
"s& = 0\nFOR i& = 1 TO 10000000\ns& = (s& + i& MOD 7) MOD 100000\nNEXT\nPRINT s&",
10_000_000.0,
"Iterationen",
);
// Gleitkomma-Schleife.
run_timed(
"DOUBLE-Schleife (5 Mio)",
"d# = 0\nFOR i& = 1 TO 5000000\nd# = d# + i& * 1.000001\nNEXT\nPRINT CINT(d# / 1000000000000#)",
5_000_000.0,
"Iterationen",
);
// Prozeduraufrufe.
run_timed(
"SUB-Aufrufe (1 Mio, BYREF)",
"SUB Inc (x&)\nx& = x& + 1\nEND SUB\nn& = 0\nFOR i& = 1 TO 1000000\nInc n&\nNEXT\nPRINT n&",
1_000_000.0,
"Aufrufe",
);
// String-Last: MID$/INSTR/Verkettung.
run_timed(
"String-Funktionen (200k)",
"s$ = \"Terminal Basic Benchmark\"\nn& = 0\nFOR i& = 1 TO 200000\nt$ = MID$(s$, (i& MOD 10) + 1, 8) + \"x\"\nn& = n& + INSTR(t$, \"a\") + LEN(t$)\nNEXT\nPRINT n& > 0",
200_000.0,
"Runden",
);
}