///|
fn workload(
count : Int32,
shape : String,
changed : Bool,
) -> (Array[String], Array[@trace.SidecarInput]) {
let files : Array[String] = []
let sources = [
@trace.SidecarInput::new(
"bold.json",
if changed {
"{\"RepetitionTime\":3.0,\"vendor\":[null,-0,9007199254740993,1e999]}"
} else {
"{\"RepetitionTime\":2.0,\"vendor\":[null,-0,9007199254740993,1e999]}"
},
),
]
for i in 0.. Int32 raise {
match phase {
"build" =>
@trace.DatasetIndex::from_manifest(files, sources).data_paths().length()
"audit" => {
let report = index.audit_all()
assert_eq(report.error_count(), 0)
report.entries().length()
}
"compare" => {
let report = index.compare(after)
assert_eq(report.error_count(), 0)
report.changed_count()
}
"serialize" => audit.to_json().length()
_ => abort("validated phase")
}
}
///|
fn argument_error(message : String) -> Unit raise {
// Release Wasm may strip failure strings; retain one complete diagnostic.
println(
Json::object({
"status": Json::string("error"),
"code": Json::string("invalid_benchmark_arguments"),
"message": Json::string(message),
}).stringify(),
)
fail(message)
}
///|
#cfg(target="js")
fn benchmark_args(raw : Array[String]) -> Array[String] {
// core/env exposes Node's [node, script, ...], unlike native/WASI argv.
if raw.length() >= 2 {
raw[1:].to_owned()
} else {
raw
}
}
///|
#cfg(not(target="js"))
fn benchmark_args(raw : Array[String]) -> Array[String] {
raw
}
///|
fn main raise {
let args = benchmark_args(@env.args())
guard args.length() == 5 else {
argument_error(
"Usage: benchmark build|audit|compare|serialize|evidence sparse|scoped|root-heavy SCANS SAMPLES",
)
return
}
let phase = args[1]
let shape = args[2]
guard ["build", "audit", "compare", "serialize", "evidence"].contains(phase) &&
["sparse", "scoped", "root-heavy"].contains(shape) else {
argument_error("Unknown phase or workload shape")
return
}
let count = @string.parse_int(args[3]) catch {
_ => {
argument_error("SCANS must be an integer")
0
}
}
let samples = @string.parse_int(args[4]) catch {
_ => {
argument_error("SAMPLES must be an integer")
0
}
}
guard count > 0 && count <= 5000 && samples >= 3 && samples <= 31 else {
argument_error("SCANS must be 1..5000; SAMPLES must be 3..31")
return
}
let (files, sources) = workload(count, shape, false)
let index = @trace.DatasetIndex::from_manifest(files, sources)
let after = if phase == "compare" || phase == "evidence" {
let (paths, inputs) = workload(count, shape, true)
@trace.DatasetIndex::from_manifest(paths, inputs)
} else {
index
}
let audit = if phase == "serialize" || phase == "evidence" {
index.audit_all()
} else {
index.audit([])
}
if phase == "evidence" {
println(
"{\"audit\":" +
audit.to_json() +
",\"impact\":" +
index.compare(after).to_json() +
",\"manifest\":" +
index.to_manifest_json() +
"}",
)
return
}
ignore(execute(phase, files, sources, index, after, audit)) // one untimed warmup
let elapsed : Array[Double] = []
let mut checksum = 0L
for _ in 0.. Json::number(value))),
"median_us": Json::number(sorted[sorted.length() / 2]),
"checksum": Json::string(checksum.to_string()),
}).stringify(),
)
}