-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
tasks.py
97 lines (79 loc) · 3.13 KB
/
tasks.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
import functools
import itertools
import multiprocessing
import operator
import random
import sys
import timeit
import invoke
run = functools.partial(invoke.Context.run, echo=True, pty=True)
@invoke.task
def install(context):
# type: (invoke.Context) -> None
run(context, f"{sys.executable} -m pip install --upgrade pip")
run(context, f"{sys.executable} -m pip install --upgrade -r requirements.txt")
@invoke.task(install)
def clean(context):
# type: (invoke.Context) -> None
run(context, f"{sys.executable} setup.py develop --uninstall")
for artifact in ("*.egg-info", "*.so", "build", "dist"):
run(context, f"rm -rf {artifact}")
run(context, f"{sys.executable} -m black .")
@invoke.task(clean)
def build(context):
# type: (invoke.Context) -> None
run(context, f"{sys.executable} setup.py develop")
@invoke.task(build)
def test(context):
# type: (invoke.Context) -> None
run(context, f"{sys.executable} -m pytest -v")
def do_work(info):
import automap
namespace = {"FrozenAutoMap": automap.FrozenAutoMap}
create_a = timeit.Timer("a = FrozenAutoMap(keys)", globals=namespace)
create_d = timeit.Timer("d = {k: i for i, k in enumerate(keys)}", globals=namespace)
access_a = timeit.Timer(
"for key in a: a[key]", "a = FrozenAutoMap(keys)", globals=namespace
)
access_d = timeit.Timer(
"for key in d: d[key]",
"d = {k: i for i, k in enumerate(keys)}",
globals=namespace,
)
kind, power, factor = info
items = factor * 10**power
namespace["keys"] = [kind(_) for _ in range(items)]
random.shuffle(namespace["keys"])
iterations = max(create_a.autorange()[0], create_d.autorange()[0])
create = create_a.timeit(iterations) / create_d.timeit(iterations)
size = sys.getsizeof(automap.FrozenAutoMap(namespace["keys"])) / sys.getsizeof(
{k: i for i, k in enumerate(namespace["keys"])}
)
iterations = max(access_a.autorange()[0], access_d.autorange()[0])
access = access_a.timeit(iterations) / access_d.timeit(iterations)
return items, create, access, size
@invoke.task(test)
def performance(context):
# type: (invoke.Context) -> None
print("TYPE\tITEMS\tCREATE\tACCESS\tSIZE")
def geometric_mean(xs):
return functools.reduce(operator.mul, xs) ** (1 / len(xs))
with multiprocessing.get_context("spawn").Pool() as pool:
for kind in (str, int):
total_create = []
total_access = []
total_size = []
for items, create, access, size in pool.imap(
do_work, itertools.product((kind,), range(6), range(1, 10))
):
print(
f"{kind.__name__}\t{items:,}\t{create-1:+.0%}\t{access-1:+.0%}\t{size-1:+.0%}",
flush=True,
)
total_create.append(create)
total_access.append(access)
total_size.append(size)
print(
f"{kind.__name__}\tMEAN\t{geometric_mean(total_create)-1:+.0%}\t{geometric_mean(total_access)-1:+.0%}\t{geometric_mean(total_size)-1:+.0%}",
flush=True,
)