Forked from epage/deduplicate_manifest_fixture.py
Last active
April 14, 2022 19:57
-
-
Save Muscraft/14f6879af27500e34584296edb468d15 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import argparse | |
import pathlib | |
import os | |
import subprocess | |
import resource | |
import shutil | |
import time | |
def main(): | |
parser = argparse.ArgumentParser() | |
parser.add_argument("--members", metavar="COUNT", type=int, default=100) | |
parser.add_argument("--step", metavar="COUNT", type=int, default=25) | |
parser.add_argument("--runs", metavar="COUNT", type=int, default=3) | |
parser.add_argument("--nest", metavar="COUNT", type=int, default=1) | |
parser.add_argument("--target", type=pathlib.Path, default="./inherit_bench") | |
parser.add_argument("--bin-folder", type=pathlib.Path, default="./inherit_bench/bins") | |
args = parser.parse_args() | |
# dict to hold times across member size | |
times = {'normal': {}, 'not-optimized': {}, 'optimized': {}} | |
print("Running benchmarks") | |
# run once with no inheritable fields and once inheritable fields | |
# range(len(run_types)) is used so x is 0 for normal and 1 for inherit | |
# this makes bool(x) = False for normal and True for inherit | |
for bin_file in os.listdir(args.bin_folder): | |
print(bin_file) | |
# step until you reach desired member count | |
for member_size in range(1, (args.members + args.step) // args.step): | |
temp_times = [] | |
# used so we get average times | |
for _run in range(args.runs): | |
workspace_root = args.target | |
package_root = workspace_root / "crates" | |
members = [] | |
for index in range(member_size * args.step): | |
name = f"package_{index}" | |
current_root = package_root / name | |
current_root.mkdir(parents=True, exist_ok=True) | |
current_manifest_path = current_root / "Cargo.toml" | |
current_manifest_path.write_text(package_manifest(name, bin_file != "normal")) | |
current_source = current_root / "src/lib.rs" | |
current_source.parent.mkdir(parents=True, exist_ok=True) | |
current_source.write_text("") | |
members.append(str(current_root.relative_to(workspace_root))) | |
if index % args.nest == 0: | |
package_root = workspace_root / "crates" | |
else: | |
package_root = current_root | |
workspace_path = workspace_root / "Cargo.toml" | |
workspace_path.write_text(workspace_manifest(members, bin_file != "normal")) | |
# direct output to temp.txt | |
with open(workspace_root / 'temp.txt', "w") as outfile: | |
# Start timer | |
usage_start = resource.getrusage(resource.RUSAGE_CHILDREN) | |
# run cargo metadata | |
subprocess.run([f"./inherit_bench/bins/./{bin_file}", "metadata", f'--manifest-path={workspace_root / "Cargo.toml"}', "--format-version", "1"], stdout=outfile) | |
# End timer | |
usage_end = resource.getrusage(resource.RUSAGE_CHILDREN) | |
# add elapsed time to temp_times | |
temp_times.append(usage_end.ru_utime - usage_start.ru_utime) | |
outfile.close() | |
# remove files created for this run | |
os.remove(workspace_root / "Cargo.toml") | |
os.remove(workspace_root / "Cargo.lock") | |
os.remove(workspace_root / "temp.txt") | |
shutil.rmtree(workspace_root / "crates") | |
# sleep to let things settle | |
time.sleep(0.25) | |
# average times across runs | |
avg_time = round(sum(temp_times) / len(temp_times), 3) | |
# add averaged time to the correct run type and member size | |
times[bin_file][member_size * args.step] = avg_time | |
# output stats by member size | |
for x in range(1, (args.members + args.step) // args.step): | |
normal = times['normal'][x * args.step] | |
no_op = times['not-optimized'][x * args.step] | |
op = times['optimized'][x * args.step] | |
change = round(((op - normal)/normal) * 100, 3) | |
op_diff = round(op - no_op, 3) | |
op_normal_diff = round(op - normal, 3) | |
print(f"\n{x * args.step} Members -- Optimized: {op}, Not Optimized: {no_op}s, Normal: {normal}s") | |
print(f" Op-No Op Diff: {op_diff}s, Op-Normal Diff: {op_normal_diff}s, Op Change from Normal: {change}%") | |
def workspace_manifest(members, inherit): | |
members = '",\n "'.join(members) | |
if inherit: | |
return f""" | |
[workspace] | |
members = [ | |
"{members}" | |
] | |
[workspace.package] | |
version = "1.0.0" | |
authors = ["Nice Folks"] | |
description = "..." | |
documentation = "https://example.github.io/example" | |
readme = "README.md" | |
homepage = "https://example.com" | |
repository = "https://github.com/example/example" | |
license = "MIT" | |
keywords = ["cli"] | |
categories = ["development-tools"] | |
publish = false | |
edition = "2018" | |
""" | |
else: | |
return f""" | |
[workspace] | |
members = [ | |
"{members}" | |
] | |
""" | |
def package_manifest(name, inherit): | |
if inherit: | |
return f""" | |
cargo-features = ["workspace-inheritance"] | |
[package] | |
name = "{name}" | |
version.workspace = true | |
authors.workspace = true | |
description.workspace = true | |
documentation.workspace = true | |
readme.workspace = true | |
homepage.workspace = true | |
repository.workspace = true | |
license.workspace = true | |
keywords.workspace = true | |
categories.workspace = true | |
publish.workspace = true | |
edition.workspace = true | |
""" | |
else: | |
return f""" | |
[package] | |
name = "{name}" | |
version = "1.0.0" | |
authors = ["Nice Folks"] | |
description = "..." | |
documentation = "https://example.github.io/example" | |
readme = "README.md" | |
homepage = "https://example.com" | |
repository = "https://github.com/example/example" | |
license = "MIT" | |
keywords = ["cli"] | |
categories = ["development-tools"] | |
publish = false | |
edition = "2018" | |
""" | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment