1 | #!/usr/bin/env python2
|
2 | """
|
3 | container_types.py
|
4 | """
|
5 | from __future__ import print_function
|
6 |
|
7 | import os
|
8 | from mycpp import mylib
|
9 | from mycpp.mylib import log
|
10 |
|
11 | from typing import List, Tuple
|
12 |
|
13 |
|
14 | def IfDemo(i):
|
15 | # type: (int) -> None
|
16 |
|
17 | if i == 1:
|
18 | print('one')
|
19 | elif i == 2:
|
20 | print('two')
|
21 | elif i == 3:
|
22 | print('three')
|
23 | elif i == 4:
|
24 | pass # no-op
|
25 | else:
|
26 | print('other number')
|
27 |
|
28 |
|
29 | class ParseError(Exception):
|
30 |
|
31 | def __init__(self, reason):
|
32 | # type: (str) -> None
|
33 | self.reason = reason
|
34 |
|
35 |
|
36 | def f(s):
|
37 | # type: (str) -> str
|
38 |
|
39 | if s[0] == 'f':
|
40 | raise ParseError('started with f')
|
41 | return s
|
42 |
|
43 |
|
44 | def ExceptDemo():
|
45 | # type: () -> None
|
46 |
|
47 | result = ''
|
48 | tmp = ['foo', 'bar']
|
49 | for prog in tmp:
|
50 | try:
|
51 | result = f(prog)
|
52 | except ParseError as e:
|
53 | log('error: %s', e.reason)
|
54 | continue
|
55 | log('result = %s', result)
|
56 |
|
57 |
|
58 | def run_tests():
|
59 | # type: () -> None
|
60 |
|
61 | tmp = [1, 2, 3, 4, 5]
|
62 | for i in tmp:
|
63 | IfDemo(i)
|
64 |
|
65 | log('')
|
66 | ExceptDemo()
|
67 |
|
68 |
|
69 | def run_benchmarks():
|
70 | # type: () -> None
|
71 |
|
72 | # BUG: we only get 8191 exceptions instead of 100,000? I think this must be
|
73 | # because of 'throw Alloc<ParseError>? TODO: Should exceptions throw by
|
74 | # value?
|
75 | n = 100000
|
76 |
|
77 | # C++ exceptions are slower than Python! Woah.
|
78 |
|
79 | result = ''
|
80 | num_exceptions = 0
|
81 | i = 0
|
82 |
|
83 | # Even one failure makes C++ slower! Otherwise it's faster.
|
84 | cases = ['fail', 'ok', 'ok', 'ok']
|
85 |
|
86 | # 870 ms in C++, 366 ms in Python
|
87 | #cases = ['fail', 'fail', 'fail', 'fail']
|
88 |
|
89 | # 26 ms in C++, 70 ms in Python
|
90 | # OK it is inverted! Exceptions are really expensive.
|
91 | #cases = ['ok', 'ok', 'ok', 'ok']
|
92 |
|
93 | while i < n:
|
94 | for prog in cases:
|
95 | try:
|
96 | result = f(prog)
|
97 | except ParseError as e:
|
98 | num_exceptions += 1
|
99 | continue
|
100 | i += 1
|
101 |
|
102 | mylib.MaybeCollect() # manual GC point
|
103 |
|
104 | log('num_exceptions = %d', num_exceptions)
|
105 | log('Ran %d iterations of try/except', n)
|
106 |
|
107 |
|
108 | if __name__ == '__main__':
|
109 | if os.getenv('BENCHMARK'):
|
110 | log('Benchmarking...')
|
111 | run_benchmarks()
|
112 | else:
|
113 | run_tests()
|