///|
fn main raise {
// Deterministic corpus: 2000 PEP 440 version strings cycling through
// release, pre/post/dev, epoch and local shapes.
let versions : Array[String] = []
for i = 0; i < 2000; i = i + 1 {
let shape = i % 5
let base = (i / 5).to_string() +
"." +
(i % 9).to_string() +
"." +
(i % 7).to_string()
let v = match shape {
0 => base
1 => base + "rc" + (i % 9).to_string()
2 => base + ".post" + (i % 5).to_string()
3 => "1!" + base + "+local" + (i % 11).to_string()
_ => base + "a1.dev" + (i % 3).to_string()
}
versions.push(v)
}
// Warm up before timing.
ignore(parse_probe(versions))
let start = @mbench.monotonic_clock_start()
let (ok, fail) = parse_probe(versions)
let micros = @mbench.monotonic_clock_end(start)
println("versions=" + versions.length().to_string())
println("parse-ok=" + ok.to_string())
println("parse-fail=" + fail.to_string())
println("parse-micros=" + micros.to_string())
if micros > 0.0 {
println("parse-us-per-version=" + (micros / 2000.0).to_string())
}
// Specifier filtering: parse once, then 2000 containment checks.
let spec = @pyversion.SpecifierSet::parse(">=1.0, !=2.3.*, <100.0")
let parsed : Array[@pyversion.Version] = []
for v in versions {
parsed.push(@pyversion.Version::parse(v))
}
let filter_start = @mbench.monotonic_clock_start()
let accepted = @pyversion.SpecifierSet::filter(parsed, spec).length()
let filter_micros = @mbench.monotonic_clock_end(filter_start)
println("filter-accepted=" + accepted.to_string())
println("filter-micros=" + filter_micros.to_string())
if filter_micros > 0.0 {
println("filter-us-per-version=" + (filter_micros / 2000.0).to_string())
}
// Round-trip checksum: parse then serialize, counting output chars.
let mut checksum = 0
for v in versions {
checksum += @pyversion.Version::to_string(@pyversion.Version::parse(v)).length()
}
println("roundtrip-char-checksum=" + checksum.to_string())
}
///|
fn parse_probe(versions : Array[String]) -> (Int, Int) {
let mut ok = 0
let mut fail = 0
for v in versions {
match
(try @pyversion.Version::parse(v) catch {
_ => false
} noraise {
_ => true
}) {
true => ok += 1
false => fail += 1
}
}
(ok, fail)
}