-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Expand file tree
/
Copy pathrun-bench.test
More file actions
196 lines (169 loc) · 5.5 KB
/
run-bench.test
File metadata and controls
196 lines (169 loc) · 5.5 KB
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
-- TODO: build some generic benchmark harness
[case testBenchmarkTree]
from typing import Optional
class Node:
def __init__(self, value: int) -> None:
self.value = value
self.left = None # type: Optional[Node]
self.right = None # type: Optional[Node]
def sum(self) -> int:
left = 0
if self.left is not None:
left = self.left.sum()
right = 0
if self.right is not None:
right = self.right.sum()
return self.value + left + right
def sum_tree(x: Optional[Node]) -> int:
if x is None:
return 0
return x.value + sum_tree(x.left) + sum_tree(x.right)
def build(n: int) -> Optional[Node]:
if n == 0:
return None
x = Node(n)
x.left = build(n - 1)
x.right = x.left
return x
def bench_sum(x: Optional[Node]) -> None:
for i in range(1000000):
sum_tree(x)
def bench_sum_method(x: Node) -> None:
for i in range(1000000):
x.sum()
[file driver.py]
from typing import Optional
import native
import interpreted
from timeit import timeit
from time import time
import os
def dumb_time(f):
t0 = time()
f()
t1 = time()
return t1 - t0
def basic_test(m):
tree = m.build(5)
assert(m.sum_tree(tree) == 57)
assert(tree.sum() == 57)
return tree
def test(m):
tree = basic_test(m)
g = {**globals(), **locals()}
sum = timeit('m.sum_tree(tree)', globals=g)
sum2 = timeit('tree.sum()', globals=g)
fsum = dumb_time(lambda: m.bench_sum(tree))
fsum2 = dumb_time(lambda: m.bench_sum_method(tree))
build = timeit('m.build(5)', globals=g)
return (sum, sum2, fsum, fsum2, build)
# Basic functionality test
basic_test(native)
# Benchmark if we are benchmarking
if os.environ.get('MYPYC_RUN_BENCH') == '1':
nsum, nsum2, nfsum, nfsum2, nbuild = test(native)
isum, isum2, ifsum, ifsum2, ibuild = test(interpreted)
print(nsum, nsum2, nfsum, nbuild)
print("Sum speedup:", isum/nsum)
print("Sum method speedup:", isum2/nsum2)
print("Sum (fast) speedup:", ifsum/nfsum)
print("Sum (fast) method speedup:", ifsum2/nfsum2)
print("Build speedup:", ibuild/nbuild)
[case testBenchmarkVisitorTree]
from mypy_extensions import trait
from typing import cast, Generic, TypeVar, Any
T = TypeVar('T')
class Tree:
def accept(self, v: 'TreeVisitor[T]') -> T:
pass
class Leaf(Tree):
def accept(self, v: 'TreeVisitor[T]') -> T:
return v.visit_leaf(self)
class Node(Tree):
def __init__(self, value: int, left: Tree, right: Tree) -> None:
self.value = value
self.left = left
self.right = right
def accept(self, v: 'TreeVisitor[T]') -> T:
return v.visit_node(self)
@trait
class TreeVisitor(Generic[T]):
def visit_leaf(self, x: Leaf) -> T: return cast(T, None)
def visit_node(self, x: Node) -> T: return cast(T, None)
class SumVisitor(TreeVisitor[int]):
def sum(self, x: Tree) -> int:
return x.accept(self)
def visit_leaf(self, x: Leaf) -> int:
return 0
def visit_node(self, x: Node) -> int:
return x.value + self.sum(x.left) + self.sum(x.right)
def equal(x: Tree, y: Tree) -> bool:
return EqualVisitor(x).equal(y)
class EqualVisitor(TreeVisitor[bool]):
def __init__(self, left: Tree) -> None:
self.left = left
def equal(self, right: Tree) -> bool:
return right.accept(self)
def visit_leaf(self, right: Leaf) -> bool:
return isinstance(self.left, Leaf)
def visit_node(self, right: Node) -> bool:
if isinstance(self.left, Node):
# our boolean stuff is crap
if (self.left.value == right.value and equal(self.left.left, right.left)
and equal(self.left.right, right.right)):
return True
return False
def sum_tree(x: Tree) -> int:
return SumVisitor().sum(x)
def build(n: int) -> Tree:
if n == 0:
return Leaf()
return Node(n, build(n - 1), build(n - 1))
def bench_sum_tree(x: Tree) -> None:
for i in range(100000):
sum_tree(x)
def bench_equal_tree(x: Tree, y: Tree) -> None:
for i in range(100000):
equal(x, y)
[file driver.py]
from typing import Optional
import interpreted
import native
from timeit import timeit
from time import time
import os
import sys
# Side test: some stuff about MROs and generics
if sys.version_info[:3] > (3, 5, 2):
assert tuple(x.__name__ for x in interpreted.SumVisitor.mro()) == ('SumVisitor', 'TreeVisitor', 'Generic', 'object')
assert tuple(x.__name__ for x in native.SumVisitor.mro()) == ('SumVisitor', 'TreeVisitor', 'Generic', 'object')
assert str(native.TreeVisitor[native.T]) == "native.TreeVisitor[~T]"
assert native.TreeVisitor.__name__ == "TreeVisitor"
assert native.SumVisitor.__name__ == "SumVisitor"
def dumb_time(f):
t0 = time()
f()
t1 = time()
return t1 - t0
def basic_test(m):
tree = m.build(5)
tree2 = m.build(5)
tree2.right.right.right.value = 10
assert m.sum_tree(tree) == 57
assert m.equal(tree, tree)
assert not m.equal(tree, tree2)
assert isinstance(native.SumVisitor(), native.TreeVisitor)
return tree
def test(m):
tree = basic_test(m)
g = {**globals(), **locals()}
fsum = dumb_time(lambda: m.bench_sum_tree(tree))
feq = dumb_time(lambda: m.bench_equal_tree(tree, tree))
return fsum, feq
basic_test(native)
if os.environ.get('MYPYC_RUN_BENCH') == '1':
nfsum, nfeq = test(native)
ifsum, ifeq = test(interpreted)
print(nfsum)
print("Sum speedup:", ifsum/nfsum)
print("Equal speedup:", ifeq/nfeq)