Skip to content

Commit f9eee44

Browse files
committed
Reduced allocations in run
1 parent 9ed5137 commit f9eee44

File tree

6 files changed

+128
-128
lines changed

6 files changed

+128
-128
lines changed

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,6 @@ docs:
2929

3030
opt: clean
3131
./opt.sh
32+
33+
profile: opt
34+
cd opt && python -m cProfile ../benchmarks/imeprofile.py 30 | less

benchmarks/fibonacci.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,28 +8,26 @@
88
t = int(sys.argv[2])
99

1010

11-
def fibo(u0: int, u1: int, i: int) -> int:
11+
def fibo(i: int) -> int:
1212
if i > 1:
13-
return fibo(u1, u0 + u1, i - 1)
14-
if i == 1:
15-
return u1
16-
return u0
13+
return fibo(i - 1) + fibo(i - 2)
14+
else:
15+
return i
1716

1817

19-
def fibo_io(u0: int, u1: int, i: int) -> IO:
18+
def fibo_io(i: int) -> IO:
2019
if i > 1:
21-
return io.defer_io(lambda: fibo_io(u1, u0 + u1, i - 1))
22-
if i == 1:
23-
return io.pure(u1)
24-
return io.pure(u0)
20+
return io.defer_io(lambda: fibo_io(i-1)).flat_map(lambda x: fibo_io(i-2).map(lambda y: x+y))
21+
else:
22+
return io.pure(i)
2523

2624

2725
def mesure(nb):
2826
l = []
2927
i = 0
30-
while i < 10 * nb:
28+
while i < nb:
3129
start = timer()
32-
fibo(0, 1, n)
30+
fibo(n)
3331
end = timer()
3432
l.append(end - start)
3533
i += 1
@@ -39,7 +37,7 @@ def mesure(nb):
3937
def mesure_io(nb):
4038
l = []
4139
i = 0
42-
mio = fibo_io(0, 1, n)
40+
mio = fibo_io(n)
4341
while i < nb:
4442
start = timer()
4543
mio.run(None)
@@ -48,6 +46,10 @@ def mesure_io(nb):
4846
i += 1
4947
return statistics.median(l)
5048

49+
x = 8
50+
51+
print(f"fibo({x})=${fibo(x)}")
52+
print(f"fibo_io({x})=${fibo_io(x).run(None).raise_on_panic()}")
5153

5254
print(f"fibo({n}) : {mesure(t)}")
5355
print(f"fibo_io({n}) : {mesure_io(t)}")

benchmarks/imeprofile.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,14 @@
44
import sys
55

66

7-
def fibo_io(u0: int, u1: int, i: int) -> IO:
7+
def fibo_io(i: int) -> IO:
88
if i > 1:
9-
return io.defer_io(lambda: fibo_io(u1, (u0 + u1) % 10000, i - 1))
10-
if i == 1:
11-
return io.pure(u1)
12-
return io.pure(u0)
9+
return io.defer_io(lambda: fibo_io(i - 1)).flat_map(lambda x: fibo_io(i-2).map(lambda y: x + y))
10+
else:
11+
return io.pure(i)
1312

1413

15-
m = fibo_io(0, 1, int(sys.argv[1]))
14+
m = fibo_io(int(sys.argv[1]))
1615

1716

1817
profiler = cProfile.Profile()

docs/io.html

Lines changed: 4 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ <h1 class="title">Module <code>raffiot.io</code></h1>
6767
Have a look to the documentation and examples to learn how to use it.
6868
&#34;&#34;&#34;
6969

70+
__slots__ = &#34;__tag&#34;, &#34;__fields&#34;
71+
7072
@final
7173
def __init__(self, __tag, __fields):
7274
self.__tag = __tag
@@ -78,8 +80,6 @@ <h1 class="title">Module <code>raffiot.io</code></h1>
7880
Transform the computed value with f if the computation is successful.
7981
Do nothing otherwise.
8082
&#34;&#34;&#34;
81-
if self.__tag in [9, 12]:
82-
return self
8383
return IO(1, (self, f))
8484

8585
@final
@@ -107,8 +107,6 @@ <h1 class="title">Module <code>raffiot.io</code></h1>
107107
and arg computes a value `x: X`
108108
then self.ap(arg) computes `f(x): A`
109109
&#34;&#34;&#34;
110-
if self.__tag == 0 and arg.__tag == 0:
111-
return IO(5, lambda: self.__fields(arg.__fields))
112110
return IO(3, (self, arg))
113111

114112
@final
@@ -128,8 +126,6 @@ <h1 class="title">Module <code>raffiot.io</code></h1>
128126
Transform the context with f.
129127
Note that f is not from R to R2 but from R2 to R!
130128
&#34;&#34;&#34;
131-
if self.__tag in [0, 5, 9, 12]:
132-
return self
133129
return IO(8, (f, self))
134130

135131
# Error API
@@ -141,8 +137,6 @@ <h1 class="title">Module <code>raffiot.io</code></h1>
141137

142138
On error, call the handler with the error.
143139
&#34;&#34;&#34;
144-
if self.__tag in [0, 5, 7, 12]:
145-
return self
146140
return IO(10, (self, handler))
147141

148142
@final
@@ -151,8 +145,6 @@ <h1 class="title">Module <code>raffiot.io</code></h1>
151145
Transform the stored error if the computation fails on an error.
152146
Do nothing otherwise.
153147
&#34;&#34;&#34;
154-
if self.__tag in [0, 5, 7, 12]:
155-
return self
156148
return IO(11, (self, f))
157149

158150
# Panic
@@ -164,8 +156,6 @@ <h1 class="title">Module <code>raffiot.io</code></h1>
164156

165157
On panic, call the handler with the exception.
166158
&#34;&#34;&#34;
167-
if self.__tag in [0, 7, 9]:
168-
return self
169159
return IO(13, (self, handler))
170160

171161
@final
@@ -174,8 +164,6 @@ <h1 class="title">Module <code>raffiot.io</code></h1>
174164
Transform the exception stored if the computation fails on a panic.
175165
Do nothing otherwise.
176166
&#34;&#34;&#34;
177-
if self.__tag in [0, 7, 9]:
178-
return self
179167
return IO(14, (self, f))
180168

181169
@final
@@ -841,6 +829,8 @@ <h2 class="section-title" id="header-classes">Classes</h2>
841829
Have a look to the documentation and examples to learn how to use it.
842830
&#34;&#34;&#34;
843831

832+
__slots__ = &#34;__tag&#34;, &#34;__fields&#34;
833+
844834
@final
845835
def __init__(self, __tag, __fields):
846836
self.__tag = __tag
@@ -852,8 +842,6 @@ <h2 class="section-title" id="header-classes">Classes</h2>
852842
Transform the computed value with f if the computation is successful.
853843
Do nothing otherwise.
854844
&#34;&#34;&#34;
855-
if self.__tag in [9, 12]:
856-
return self
857845
return IO(1, (self, f))
858846

859847
@final
@@ -881,8 +869,6 @@ <h2 class="section-title" id="header-classes">Classes</h2>
881869
and arg computes a value `x: X`
882870
then self.ap(arg) computes `f(x): A`
883871
&#34;&#34;&#34;
884-
if self.__tag == 0 and arg.__tag == 0:
885-
return IO(5, lambda: self.__fields(arg.__fields))
886872
return IO(3, (self, arg))
887873

888874
@final
@@ -902,8 +888,6 @@ <h2 class="section-title" id="header-classes">Classes</h2>
902888
Transform the context with f.
903889
Note that f is not from R to R2 but from R2 to R!
904890
&#34;&#34;&#34;
905-
if self.__tag in [0, 5, 9, 12]:
906-
return self
907891
return IO(8, (f, self))
908892

909893
# Error API
@@ -915,8 +899,6 @@ <h2 class="section-title" id="header-classes">Classes</h2>
915899

916900
On error, call the handler with the error.
917901
&#34;&#34;&#34;
918-
if self.__tag in [0, 5, 7, 12]:
919-
return self
920902
return IO(10, (self, handler))
921903

922904
@final
@@ -925,8 +907,6 @@ <h2 class="section-title" id="header-classes">Classes</h2>
925907
Transform the stored error if the computation fails on an error.
926908
Do nothing otherwise.
927909
&#34;&#34;&#34;
928-
if self.__tag in [0, 5, 7, 12]:
929-
return self
930910
return IO(11, (self, f))
931911

932912
# Panic
@@ -938,8 +918,6 @@ <h2 class="section-title" id="header-classes">Classes</h2>
938918

939919
On panic, call the handler with the exception.
940920
&#34;&#34;&#34;
941-
if self.__tag in [0, 7, 9]:
942-
return self
943921
return IO(13, (self, handler))
944922

945923
@final
@@ -948,8 +926,6 @@ <h2 class="section-title" id="header-classes">Classes</h2>
948926
Transform the exception stored if the computation fails on a panic.
949927
Do nothing otherwise.
950928
&#34;&#34;&#34;
951-
if self.__tag in [0, 7, 9]:
952-
return self
953929
return IO(14, (self, f))
954930

955931
@final
@@ -1219,8 +1195,6 @@ <h3>Methods</h3>
12191195
and arg computes a value `x: X`
12201196
then self.ap(arg) computes `f(x): A`
12211197
&#34;&#34;&#34;
1222-
if self.__tag == 0 and arg.__tag == 0:
1223-
return IO(5, lambda: self.__fields(arg.__fields))
12241198
return IO(3, (self, arg))</code></pre>
12251199
</details>
12261200
</dd>
@@ -1284,8 +1258,6 @@ <h3>Methods</h3>
12841258

12851259
On error, call the handler with the error.
12861260
&#34;&#34;&#34;
1287-
if self.__tag in [0, 5, 7, 12]:
1288-
return self
12891261
return IO(10, (self, handler))</code></pre>
12901262
</details>
12911263
</dd>
@@ -1305,8 +1277,6 @@ <h3>Methods</h3>
13051277
Transform the context with f.
13061278
Note that f is not from R to R2 but from R2 to R!
13071279
&#34;&#34;&#34;
1308-
if self.__tag in [0, 5, 9, 12]:
1309-
return self
13101280
return IO(8, (f, self))</code></pre>
13111281
</details>
13121282
</dd>
@@ -1390,8 +1360,6 @@ <h3>Methods</h3>
13901360
Transform the computed value with f if the computation is successful.
13911361
Do nothing otherwise.
13921362
&#34;&#34;&#34;
1393-
if self.__tag in [9, 12]:
1394-
return self
13951363
return IO(1, (self, f))</code></pre>
13961364
</details>
13971365
</dd>
@@ -1411,8 +1379,6 @@ <h3>Methods</h3>
14111379
Transform the stored error if the computation fails on an error.
14121380
Do nothing otherwise.
14131381
&#34;&#34;&#34;
1414-
if self.__tag in [0, 5, 7, 12]:
1415-
return self
14161382
return IO(11, (self, f))</code></pre>
14171383
</details>
14181384
</dd>
@@ -1432,8 +1398,6 @@ <h3>Methods</h3>
14321398
Transform the exception stored if the computation fails on a panic.
14331399
Do nothing otherwise.
14341400
&#34;&#34;&#34;
1435-
if self.__tag in [0, 7, 9]:
1436-
return self
14371401
return IO(14, (self, f))</code></pre>
14381402
</details>
14391403
</dd>
@@ -1492,8 +1456,6 @@ <h3>Methods</h3>
14921456

14931457
On panic, call the handler with the exception.
14941458
&#34;&#34;&#34;
1495-
if self.__tag in [0, 7, 9]:
1496-
return self
14971459
return IO(13, (self, handler))</code></pre>
14981460
</details>
14991461
</dd>

0 commit comments

Comments
 (0)