874b6f20c2
Основа — Horizon (MIT). История апстрима не переносится: этот репозиторий ведёт свою.
65 lines
2.5 KiB
Python
65 lines
2.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Profile the validation and typed-deserialization passes in separate processes.
|
|
|
|
Build `cargo build --release -p horizon-client --example gameplay_decode_profile`
|
|
then run this tool with the matching prepared resources. These passes are
|
|
both currently required for exact JSON error classification/precedence.
|
|
"""
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
import os
|
|
import statistics
|
|
from pathlib import Path
|
|
from profile_shared_json import percentile, run
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--binary", type=Path,
|
|
default=Path("target/release/examples/gameplay_decode_profile"))
|
|
parser.add_argument("--resources", type=Path, default=Path(".local/horizon-client/26.3"))
|
|
parser.add_argument("--repeats", type=int, default=8)
|
|
parser.add_argument("--output", type=Path)
|
|
args = parser.parse_args()
|
|
if args.repeats < 1:
|
|
parser.error("--repeats must be positive")
|
|
binary, resources = args.binary.resolve(), args.resources.resolve()
|
|
if not binary.is_file() or not resources.is_dir():
|
|
parser.error("release example or resources missing")
|
|
modes = ("validate", "typed")
|
|
samples = {mode: [] for mode in modes}
|
|
loads = [os.getloadavg()]
|
|
for i in range(args.repeats):
|
|
for mode in (modes if i % 2 == 0 else reversed(modes)):
|
|
samples[mode].append(run(binary, resources, mode))
|
|
loads.append(os.getloadavg())
|
|
result = {
|
|
"scope": "Isolated gameplay-facts.json validation/typed decoding; includes JSON file read",
|
|
"resources": str(resources),
|
|
"repeats": args.repeats,
|
|
"load_averages_before_after": loads,
|
|
"binary_sha256": hashlib.sha256(binary.read_bytes()).hexdigest(),
|
|
"metrics": {
|
|
mode: {
|
|
key: {"median": round(statistics.median(values), 3),
|
|
"p25": round(percentile(values, .25), 3),
|
|
"p75": round(percentile(values, .75), 3),
|
|
"min": round(min(values), 3), "max": round(max(values), 3),
|
|
"samples": [round(x, 3) for x in values]}
|
|
for key in rows[0]
|
|
for values in [[row[key] for row in rows]]
|
|
}
|
|
for mode, rows in samples.items()
|
|
},
|
|
}
|
|
data = json.dumps(result, indent=2)
|
|
print(data)
|
|
if args.output:
|
|
args.output.parent.mkdir(parents=True, exist_ok=True)
|
|
args.output.write_text(data + "\n")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|