#12: All 5 untranslated SpeckDL patterns now emit valid JS: - notIn → !.has(), old() → drop, union → Set spread, set diff → filter, append() → [...X, Y], length() → .length - ==/!= operator replacement fixed (word-boundary regression) - Postcondition object comparisons get @ts-expect-error TS2839 #11: Generator auto-detects opaque identifier types used in state variables and action params, emits 'type X = any' before class. - State properties use ! (non-null assertion) for strict mode TigerBeetleLedger → tsc --noEmit = 0 errors. 37/37 tests pass.
This commit is contained in:
parent
29d4c83d76
commit
8b520284cb
31 changed files with 3934 additions and 973 deletions
155
bench-rust.sh
Normal file
155
bench-rust.sh
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
#!/bin/bash
|
||||
# Benchmark Speck-generated Rust output
|
||||
set -e
|
||||
cd /home/sscoble/speckl
|
||||
|
||||
regen=0
|
||||
|
||||
bench_spec() {
|
||||
local SPEC=$1
|
||||
local BENCH_DIR="out/${SPEC}-bench"
|
||||
local PROLOGUE=$2
|
||||
local CONSTRUCT=$3
|
||||
local OPS=$4
|
||||
|
||||
echo "=== $SPEC ==="
|
||||
|
||||
if [ "$regen" -eq 1 ]; then
|
||||
node compiler/dist/index.js "examples/$SPEC.speck" --target=rust 2>/dev/null
|
||||
fi
|
||||
|
||||
mkdir -p "$BENCH_DIR/src"
|
||||
cp "out/$SPEC/src/lib.rs" "$BENCH_DIR/src/lib.rs"
|
||||
|
||||
# Add type defs and fix Option syntax
|
||||
cat > "$BENCH_DIR/src/lib_patched.rs" << 'EOF'
|
||||
// Auto-generated type definitions
|
||||
pub type NodeId = u64;
|
||||
pub type LogEntry = String;
|
||||
pub type Account = String;
|
||||
pub type Transfer = String;
|
||||
pub type TransferId = u64;
|
||||
pub type PageId = u64;
|
||||
pub type PageData = u64;
|
||||
pub type Frame = u64;
|
||||
pub type FrameId = u64;
|
||||
EOF
|
||||
|
||||
cat "$BENCH_DIR/src/lib.rs" >> "$BENCH_DIR/src/lib_patched.rs"
|
||||
mv "$BENCH_DIR/src/lib_patched.rs" "$BENCH_DIR/src/lib.rs"
|
||||
|
||||
# Create Cargo.toml with benchmark profile
|
||||
cat > "$BENCH_DIR/Cargo.toml" << 'CTOML'
|
||||
[package]
|
||||
name = "speck-bench"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[[bench]]
|
||||
name = "bench"
|
||||
harness = false
|
||||
|
||||
[profile.bench]
|
||||
debug = 0
|
||||
lto = "fat"
|
||||
codegen-units = 1
|
||||
CTOML
|
||||
|
||||
# Create benchmark
|
||||
mkdir -p "$BENCH_DIR/benches"
|
||||
cat > "$BENCH_DIR/benches/bench.rs" << 'BRS'
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
#[path = "../src/lib.rs"]
|
||||
mod generated;
|
||||
|
||||
BRS
|
||||
|
||||
# Add spec-specific benchmark
|
||||
{
|
||||
echo "use generated::*;"
|
||||
echo ""
|
||||
echo "fn main() {"
|
||||
echo " let iterations = 100000;"
|
||||
echo " println!(\"Benchmarking $SPEC...\");"
|
||||
echo ""
|
||||
echo " // Instantiation benchmark"
|
||||
echo " let start = Instant::now();"
|
||||
echo " for i in 0..iterations {"
|
||||
echo " let mut m = $CONSTRUCT;"
|
||||
echo " let _ = m;"
|
||||
echo " }"
|
||||
echo " let elapsed = start.elapsed();"
|
||||
echo " let per = elapsed / iterations;"
|
||||
echo " println!(\" Instantiate x{}:\", iterations);"
|
||||
echo " println!(\" Total: {:?}\", elapsed);"
|
||||
echo " println!(\" Per op: {:?}\", per);"
|
||||
echo " println!(\" Ops/sec: {:.0}\", iterations as f64 / elapsed.as_secs_f64());"
|
||||
echo ""
|
||||
echo " // Operational benchmark"
|
||||
echo " let mut total_ops = 0u64;"
|
||||
echo " let start = Instant::now();"
|
||||
echo " for i in 0..iterations {"
|
||||
echo $PROLOGUE
|
||||
echo " }"
|
||||
echo " let elapsed = start.elapsed();"
|
||||
echo " let per = elapsed / total_ops;"
|
||||
echo " println!(\" Operations x{} ({} ops):\", iterations, total_ops);"
|
||||
echo " let rate = total_ops as f64 / elapsed.as_secs_f64();"
|
||||
echo " println!(\" Total: {:?}\", elapsed);"
|
||||
echo " println!(\" Per op: {:?}\", per);"
|
||||
echo " if rate > 1_000_000.0 {"
|
||||
echo " println!(\" Rate: {:.0} M ops/sec\", rate / 1_000_000.0);"
|
||||
echo " } else if rate > 1_000.0 {"
|
||||
echo " println!(\" Rate: {:.0} K ops/sec\", rate / 1_000.0);"
|
||||
echo " } else {"
|
||||
echo " println!(\" Rate: {:.0} ops/sec\", rate);"
|
||||
echo " }"
|
||||
echo "}"
|
||||
} >> "$BENCH_DIR/benches/bench.rs"
|
||||
}
|
||||
|
||||
# KafkaKRaft benchmark
|
||||
bench_spec "KafkaKRaft" \
|
||||
' let mut m = KafkaKRaftMachine::new();
|
||||
let _ = m.request_vote(2, 1, 0);
|
||||
let _ = m.append_entries(2);
|
||||
let _ = m.handle_request_vote_request(2, 1, 0, 0);
|
||||
total_ops += 3;' \
|
||||
'KafkaKRaftMachine::new()' \
|
||||
3
|
||||
|
||||
# SQLitePager benchmark
|
||||
bench_spec "SQLitePager" \
|
||||
' let mut m = SQLitePagerMachine::new();
|
||||
let _ = m.begin_read_transaction();
|
||||
let _ = m.begin_write_transaction();
|
||||
let _ = m.write_page(1, 100);
|
||||
let _ = m.commit_transaction();
|
||||
total_ops += 4;' \
|
||||
'SQLitePagerMachine::new()' \
|
||||
4
|
||||
|
||||
# TigerBeetleLedger benchmark
|
||||
bench_spec "TigerBeetleLedger" \
|
||||
' let mut m = TigerBeetleLedgerMachine::new();
|
||||
let _ = m.create_account(1, 1000, 0);
|
||||
let _ = m.create_account(2, 0, 0);
|
||||
let _ = m.create_transfer(1, 1, 2, 100, 0);
|
||||
total_ops += 3;' \
|
||||
'TigerBeetleLedgerMachine::new()' \
|
||||
3
|
||||
|
||||
echo ""
|
||||
echo "=== Building benchmarks ==="
|
||||
for D in out/KafkaKRaft-bench out/SQLitePager-bench out/TigerBeetleLedger-bench; do
|
||||
echo "Building $D..."
|
||||
(cd "$D" && cargo bench --no-run 2>&1 | tail -5)
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "=== Running benchmarks ==="
|
||||
for D in out/KafkaKRaft-bench out/SQLitePager-bench out/TigerBeetleLedger-bench; do
|
||||
echo ""
|
||||
(cd "$D" && cargo bench 2>&1)
|
||||
done
|
||||
Loading…
Add table
Add a link
Reference in a new issue