-
Notifications
You must be signed in to change notification settings - Fork 0
/
benchmark.py
119 lines (97 loc) · 2.77 KB
/
benchmark.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import platform
import sys
from dataclasses import dataclass
from enum import Enum
from timeit import timeit
import typer
from levdist import levenshtein
try:
from leven import levenshtein
LEVEN_PRESENT = True
except ImportError:
LEVEN_PRESENT = False
ITERATIONS = 1_000_000
# `leven` has some hacks that remove same prefix and suffix.
# To measure it fair I adjusted the strings.
S1 = "1Levenshtein1"
S2 = "2Frankenstein2"
DISTANCE = levenshtein(S1, S2)
@dataclass(frozen=True)
class PackageToTest:
name: str
pypi: str
setup: str
call: str
PACKAGES = [
PackageToTest(
"levdist",
"https://pypi.org/project/levdist/",
"from levdist import levenshtein",
f"levenshtein('{S1}', '{S2}')",
),
PackageToTest(
"Levenshtein",
"https://pypi.org/project/levenshtein/",
"from Levenshtein import distance",
f"distance('{S1}', '{S2}')",
),
PackageToTest(
"pylev",
"https://pypi.org/project/pylev/",
"from pylev import levenshtein",
f"levenshtein('{S1}', '{S2}')",
),
]
if LEVEN_PRESENT:
PACKAGES.append(
PackageToTest(
"leven",
"https://pypi.org/project/leven/",
"from leven import levenshtein",
f"levenshtein('{S1}', '{S2}')",
)
)
class OutputFormat(str, Enum):
TEXT = "txt"
MARKDOWN = "md"
def benchmark(pkg: PackageToTest) -> float:
exec(
f"""
{pkg.setup}
assert {pkg.call} == {DISTANCE}
"""
)
result = timeit(
setup=pkg.setup,
stmt=pkg.call,
number=ITERATIONS,
)
return result / ITERATIONS
def main(
output: typer.FileTextWrite = typer.Argument(sys.stdout),
format: OutputFormat = typer.Option(OutputFormat.TEXT),
) -> None:
with typer.progressbar(PACKAGES) as pkgs:
results = tuple((benchmark(pkg) for pkg in pkgs))
if format == OutputFormat.TEXT:
for pkg, duration in zip(PACKAGES, results):
typer.echo(f"{pkg.name} ({pkg.pypi}): {duration} sec", output)
elif format == OutputFormat.MARKDOWN:
typer.echo(f"# Benchmark ({ITERATIONS} iterations)", output)
typer.echo(file=output)
typer.echo("| OS | CPU | Python |", output)
typer.echo("| -- | --- | ------ |", output)
typer.echo(
f"| {platform.system()} {platform.release()} | {platform.processor()} | {sys.version} |",
output,
)
typer.echo(
"""
| Package | Duration of one iteration (sec) |
| ------- | ------------------------- |""",
output,
)
for pkg, duration in zip(PACKAGES, results):
typer.echo(f"| [{pkg.name}]({pkg.pypi}) | {duration} |", output)
if __name__ == "__main__":
typer.run(main)