Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Muscraft/14f6879af27500e34584296edb468d15 to your computer and use it in GitHub Desktop.
Save Muscraft/14f6879af27500e34584296edb468d15 to your computer and use it in GitHub Desktop.
#!/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