mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-24 06:14:01 +08:00
The differential and llvm-differential corpus split their programs across the ten Linux test shards by a hash of the program's name, so a shard's share of the measured work varied from 565 to 913 s (plain) and 868 to 1358 s (sanitized). corpusSelect assigns programs longest first to the lightest shard by their measured cost per flavor (tests/harness/corpus-costs.json: the differential plus llvm-differential milliseconds on a CI runner, medians of four green main runs), giving 740-741 s and 1098-1099 s. Both harnesses still select identically, so a shard's compile cache serves both. Programs without a measurement weigh as much as the median one. scripts/ci-corpus-costs.mjs refreshes the table from downloaded CI shard logs.
44 lines
2.0 KiB
JavaScript
44 lines
2.0 KiB
JavaScript
#!/usr/bin/env node
|
|
// Refreshes tests/harness/corpus-costs.json from the logs of the Linux test shards of green CI runs on main.
|
|
//
|
|
// Usage: node scripts/ci-corpus-costs.mjs <job log> ...
|
|
//
|
|
// Each log is a downloaded "test (Linux, plain|san, i/10)" job log. vitest prints every case slower than its
|
|
// threshold with its duration; for each program this takes the median of its differential and of its
|
|
// llvm-differential case over the logs of its flavor, and stores their sum. Programs without a measurement keep
|
|
// their current value.
|
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
|
|
const path = new URL("../tests/harness/corpus-costs.json", import.meta.url);
|
|
const table = JSON.parse(readFileSync(path, "utf8"));
|
|
const samples = { plain: {}, san: {} };
|
|
for (const log of process.argv.slice(2)) {
|
|
// Logs keep the terminal color codes (ESC [ ... m); drop them before matching.
|
|
const text = readFileSync(log, "utf8")
|
|
.replaceAll(String.fromCharCode(27), "")
|
|
.replace(/\[[0-9;]*m/g, "");
|
|
const flavor = /SCRIPTC_SAN: 1\b/.test(text) ? "san" : "plain";
|
|
for (const line of text.split("\n")) {
|
|
const m =
|
|
/^\S+\s+✓ (llvm differential corpus|differential corpus) \(.*?\) > (.*?) {2}(\d+)ms$/.exec(
|
|
line,
|
|
);
|
|
if (!m) continue;
|
|
const lane = m[1] === "differential corpus" ? "differential" : "llvm";
|
|
(samples[flavor][m[2]] ??= { differential: [], llvm: [] })[lane].push(Number(m[3]));
|
|
}
|
|
}
|
|
const median = (values) => [...values].sort((a, b) => a - b)[Math.floor(values.length / 2)] ?? 0;
|
|
let updated = 0;
|
|
for (const flavor of ["plain", "san"])
|
|
for (const [key, lanes] of Object.entries(samples[flavor])) {
|
|
table[flavor][key] = median(lanes.differential) + median(lanes.llvm);
|
|
updated++;
|
|
}
|
|
for (const flavor of ["plain", "san"])
|
|
table[flavor] = Object.fromEntries(
|
|
Object.entries(table[flavor]).sort(([a], [b]) => a.localeCompare(b)),
|
|
);
|
|
writeFileSync(path, JSON.stringify(table, null, 2) + "\n");
|
|
console.log(`updated ${updated} program costs`);
|