OILS / mycpp / examples / control_flow.py View on Github | oilshell.org

113 lines, 62 significant
1#!/usr/bin/env python2
2"""
3container_types.py
4"""
5from __future__ import print_function
6
7import os
8from mycpp import mylib
9from mycpp.mylib import log
10
11from typing import List, Tuple
12
13
14def 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
29class ParseError(Exception):
30
31 def __init__(self, reason):
32 # type: (str) -> None
33 self.reason = reason
34
35
36def f(s):
37 # type: (str) -> str
38
39 if s[0] == 'f':
40 raise ParseError('started with f')
41 return s
42
43
44def 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
58def 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
69def 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
108if __name__ == '__main__':
109 if os.getenv('BENCHMARK'):
110 log('Benchmarking...')
111 run_benchmarks()
112 else:
113 run_tests()