Skip to content

Commit 3fad40f

Browse files
add -r, --dont-setup, epilog, and total time
1 parent db76d22 commit 3fad40f

File tree

1 file changed

+56
-21
lines changed

1 file changed

+56
-21
lines changed

misc/perf_compare.py

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,15 @@ def build_mypy(target_dir: str) -> None:
4444
subprocess.run(cmd, env=env, check=True, cwd=target_dir)
4545

4646

47-
def clone(target_dir: str, commit: str | None) -> None:
48-
heading(f"Cloning mypy to {target_dir}")
49-
repo_dir = os.getcwd()
47+
def clone(target_dir: str, commit: str | None, repo_source: str | None = None) -> None:
48+
source_name = repo_source or "mypy"
49+
heading(f"Cloning {source_name} to {target_dir}")
50+
if repo_source is None:
51+
repo_source = os.getcwd()
5052
if os.path.isdir(target_dir):
5153
print(f"{target_dir} exists: deleting")
5254
shutil.rmtree(target_dir)
53-
subprocess.run(["git", "clone", repo_dir, target_dir], check=True)
55+
subprocess.run(["git", "clone", repo_source, target_dir], check=True)
5456
if commit:
5557
subprocess.run(["git", "checkout", commit], check=True, cwd=target_dir)
5658

@@ -64,7 +66,7 @@ def edit_python_file(fnam: str) -> None:
6466

6567

6668
def run_benchmark(
67-
compiled_dir: str, check_dir: str, *, incremental: bool, code: str | None
69+
compiled_dir: str, check_dir: str, *, incremental: bool, code: str, foreign: bool | None
6870
) -> float:
6971
cache_dir = os.path.join(compiled_dir, ".mypy_cache")
7072
if os.path.isdir(cache_dir) and not incremental:
@@ -76,6 +78,8 @@ def run_benchmark(
7678
cmd = [sys.executable, "-m", "mypy"]
7779
if code:
7880
cmd += ["-c", code]
81+
elif foreign:
82+
pass
7983
else:
8084
cmd += ["--config-file", os.path.join(abschk, "mypy_self_check.ini")]
8185
cmd += glob.glob(os.path.join(abschk, "mypy/*.py"))
@@ -86,18 +90,28 @@ def run_benchmark(
8690
edit_python_file(os.path.join(abschk, "mypy/test/testcheck.py"))
8791
t0 = time.time()
8892
# Ignore errors, since some commits being measured may generate additional errors.
89-
subprocess.run(cmd, cwd=compiled_dir, env=env)
93+
if foreign:
94+
subprocess.run(cmd, cwd=check_dir, env=env)
95+
else:
96+
subprocess.run(cmd, cwd=compiled_dir, env=env)
9097
return time.time() - t0
9198

9299

93100
def main() -> None:
94-
parser = argparse.ArgumentParser()
101+
whole_program_time_0 = time.time()
102+
parser = argparse.ArgumentParser(epilog="Remember: you usually want the first argument to this command to be 'master'.")
95103
parser.add_argument(
96104
"--incremental",
97105
default=False,
98106
action="store_true",
99107
help="measure incremental run (fully cached)",
100108
)
109+
parser.add_argument(
110+
"--dont-setup",
111+
default=False,
112+
action="store_true",
113+
help="don't make the dirs or compile mypy, just run the performance measurement benchmark",
114+
)
101115
parser.add_argument(
102116
"--num-runs",
103117
metavar="N",
@@ -112,6 +126,14 @@ def main() -> None:
112126
type=int,
113127
help="set maximum number of parallel builds (default=8)",
114128
)
129+
parser.add_argument(
130+
"-r",
131+
metavar="FOREIGN_REPOSITORY",
132+
default=None,
133+
type=str,
134+
help="measure time to type check the project at FOREIGN_REPOSITORY instead of mypy self-check; " +
135+
"provided value must be the URL or path of a git repo",
136+
)
115137
parser.add_argument(
116138
"-c",
117139
metavar="CODE",
@@ -122,10 +144,12 @@ def main() -> None:
122144
parser.add_argument("commit", nargs="+", help="git revision to measure (e.g. branch name)")
123145
args = parser.parse_args()
124146
incremental: bool = args.incremental
147+
dont_setup: bool = args.dont_setup
125148
commits = args.commit
126149
num_runs: int = args.num_runs + 1
127150
max_workers: int = args.j
128151
code: str | None = args.c
152+
foreign_repo: str | None = args.r
129153

130154
if not (os.path.isdir(".git") and os.path.isdir("mypyc")):
131155
sys.exit("error: Run this the mypy repo root")
@@ -134,20 +158,28 @@ def main() -> None:
134158
for i, commit in enumerate(commits):
135159
target_dir = f"mypy.{i}.tmpdir"
136160
target_dirs.append(target_dir)
137-
clone(target_dir, commit)
161+
if not dont_setup:
162+
clone(target_dir, commit)
138163

139-
self_check_dir = "mypy.self.tmpdir"
140-
clone(self_check_dir, commits[0])
164+
if foreign_repo:
165+
check_dir = "mypy.foreign.tmpdir"
166+
if not dont_setup:
167+
clone(check_dir, None, foreign_repo)
168+
else:
169+
check_dir = "mypy.self.tmpdir"
170+
if not dont_setup:
171+
clone(check_dir, commits[0])
141172

142-
heading("Compiling mypy")
143-
print("(This will take a while...)")
173+
if not dont_setup:
174+
heading("Compiling mypy")
175+
print("(This will take a while...)")
144176

145-
with ThreadPoolExecutor(max_workers=max_workers) as executor:
146-
futures = [executor.submit(build_mypy, target_dir) for target_dir in target_dirs]
147-
for future in as_completed(futures):
148-
future.result()
177+
with ThreadPoolExecutor(max_workers=max_workers) as executor:
178+
futures = [executor.submit(build_mypy, target_dir) for target_dir in target_dirs]
179+
for future in as_completed(futures):
180+
future.result()
149181

150-
print(f"Finished compiling mypy ({len(commits)} builds)")
182+
print(f"Finished compiling mypy ({len(commits)} builds)")
151183

152184
heading("Performing measurements")
153185

@@ -160,7 +192,7 @@ def main() -> None:
160192
items = list(enumerate(commits))
161193
random.shuffle(items)
162194
for i, commit in items:
163-
tt = run_benchmark(target_dirs[i], self_check_dir, incremental=incremental, code=code)
195+
tt = run_benchmark(target_dirs[i], check_dir, incremental=incremental, code=code, foreign=bool(foreign_repo))
164196
# Don't record the first warm-up run
165197
if n > 0:
166198
print(f"{commit}: t={tt:.3f}s")
@@ -171,16 +203,19 @@ def main() -> None:
171203
first = -1.0
172204
for commit in commits:
173205
tt = statistics.mean(results[commit])
174-
s = statistics.stdev(results[commit])
206+
#pstdev (instead of stdev) is used here primarily to accommodate the case where num_runs=1
207+
s = statistics.pstdev(results[commit]) if len(results[commit]) > 1 else 0
175208
if first < 0:
176209
delta = "0.0%"
177210
first = tt
178211
else:
179212
d = (tt / first) - 1
180213
delta = f"{d:+.1%}"
181-
print(f"{commit:<25} {tt:.3f}s ({delta}) | stdev {s}")
214+
print(f"{commit:<25} {tt:.3f}s ({delta}) | stdev {s:.3f}s ")
215+
216+
print(f"Total time taken by the benchmarking program (including any setup): {time.time() - whole_program_time_0:.2f}s")
182217

183-
shutil.rmtree(self_check_dir)
218+
shutil.rmtree(check_dir)
184219
for target_dir in target_dirs:
185220
shutil.rmtree(target_dir)
186221

0 commit comments

Comments
 (0)