| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- -- 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)
|