Files
scriptc/packages/cli/test/optimization.test.ts
Malte Ubl 2372b75ec2 Add an opt-in --optimization=speed posture
Speed is a third native optimization posture next to release (default,
-O2) and dev (-O0). It is optimized exactly like release at the C/LLVM
level and is the switch for optimizations that trade executable size and
build time for run-time speed, so the default release build stays inside
the binary-size budget.

- backend/optimization.ts: the NativeOptimization type, its -O class, and
  cache-key helpers. Release keeps its historical key shapes (absent).
- CLI: build/run/cache warm accept speed; usage text names the trade.
  Bootstrap's routed executable cache mirrors the posture.
- Early executable cache keys and native-feature validation include speed,
  so release, dev, and speed entries never satisfy one another.
- Runtime packs: an optional executable `speed` flavor (-O2, only beside
  release). Speed links it when present and the release objects otherwise;
  library modes link their release flavor. The sanitizer lane follows the
  same flavor key.
- Library profiles accept "speed".
- WASI release-only linker flags apply to speed too.
- bench-runtime: --baseline-optimization/--candidate-optimization and a
  per-contender cold_build_ms.

Release executables are byte-identical to the stack tip for all 14
benchmark workloads (macOS arm64, sha256 of executables built from both
trees).
2026-10-08 15:46:34 -05:00

45 lines
1.7 KiB
TypeScript

import { execFile } from "node:child_process";
import { mkdtemp, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { promisify } from "node:util";
import { expect, test } from "vitest";
const execFileAsync = promisify(execFile);
const repoRoot = join(import.meta.dirname, "../../..");
const bootstrap = join(repoRoot, "packages/cli/dist/bootstrap.js");
test("--optimization accepts release, dev, and speed and names them when rejecting", async () => {
const dir = await mkdtemp(join(tmpdir(), "scriptc-cli-optimization-"));
try {
const entry = join(dir, "main.ts");
await writeFile(entry, 'console.log("posture");\n');
const env = { ...process.env, SCRIPTC_CACHE_DIR: join(dir, "cache") };
const help = await execFileAsync(process.execPath, [bootstrap, "--help"], { env });
expect(help.stdout).toContain("--optimization <release|dev|speed>");
for (const args of [
["build", entry, "--optimization=fast"],
["run", entry, "--optimization", "O3"],
["cache", "warm", "--optimization=fast"],
]) {
await expect(
execFileAsync(process.execPath, [bootstrap, ...args], { env }),
).rejects.toMatchObject({
stderr: expect.stringContaining("(supported: release, dev, speed)"),
});
}
// Speed is an executable posture like release and dev.
await expect(
execFileAsync(
process.execPath,
[bootstrap, "build", entry, "--emit=llvm", "--optimization=speed"],
{ env },
),
).rejects.toMatchObject({
stderr: expect.stringContaining("--optimization is only meaningful with --emit=exe"),
});
} finally {
await rm(dir, { recursive: true, force: true });
}
}, 60_000);