git.iko.soy/effects-benchmarks
on master help sign in
README.md+334−51
since splitsnapshots
unifiedsplit
@@ -1,105 +1,388 @@
1# effects-benchmarks
1# effects-benchmarks
2
2
3−This is a set of memory and time benchmarks for the various Haskell effects libraries, including `fused-effects`, `polysemy`, `freer-simple`, and `extensible-effects`. Benchmarks for equivalent `mtl` and handwritten computations are included for comparison purposes. It uses Cabal's new Backpack feature to save a great deal of boilerplate code.
4
3
5−# tl;dr
4+## Results
6
5
7−`fused-effects` and `mtl` achieve roughly commensurate performance. `polysemy` is within one to three orders of magnitude from `fused-effects` and `mtl`. `freer-simple` and `extensible-effects` are considerably slower.
6+<details>
8
7
9−# Full results
8+<summary>Linux – Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz</summary>
10−
11−On a 15-inch 2017 MacBook Pro (3.1GHz Intel i7, 16GB RAM), here are results for space benchmarks:
12
9
13```
10```
11+*** Time benchmarks ***
12+benchmarked Countdown/Put/fused-effects
13+time 13.54 ms (13.44 ms .. 13.67 ms)
14+ 0.999 R² (0.998 R² .. 1.000 R²)
15+mean 13.58 ms (13.54 ms .. 13.69 ms)
16+std dev 165.6 μs (94.38 μs .. 276.3 μs)
17+
18+benchmarked Countdown/Put/mtl
19+time 4.885 ms (4.777 ms .. 4.954 ms)
20+ 0.998 R² (0.993 R² .. 1.000 R²)
21+mean 4.995 ms (4.934 ms .. 5.227 ms)
22+std dev 333.6 μs (54.64 μs .. 696.6 μs)
23+variance introduced by outliers: 37% (moderately inflated)
24+
25+benchmarked Countdown/Put/polysemy
26+time 20.82 ms (20.58 ms .. 21.10 ms)
27+ 0.999 R² (0.997 R² .. 1.000 R²)
28+mean 20.82 ms (20.70 ms .. 21.00 ms)
29+std dev 359.1 μs (243.7 μs .. 578.8 μs)
30+
31+benchmarked Countdown/Put/freer-simple
32+time 20.18 ms (19.82 ms .. 20.56 ms)
33+ 0.998 R² (0.997 R² .. 0.999 R²)
34+mean 19.90 ms (19.56 ms .. 20.53 ms)
35+std dev 1.084 ms (524.8 μs .. 2.078 ms)
36+variance introduced by outliers: 22% (moderately inflated)
37+
38+benchmarked Countdown/Put/extensible-effects
39+time 22.01 ms (21.29 ms .. 22.72 ms)
40+ 0.997 R² (0.995 R² .. 0.999 R²)
41+mean 20.74 ms (19.73 ms .. 21.26 ms)
42+std dev 1.554 ms (611.3 μs .. 2.309 ms)
43+variance introduced by outliers: 30% (moderately inflated)
44+
45+benchmarked Countdown/Put/shallow
46+time 2.432 ms (2.390 ms .. 2.477 ms)
47+ 0.998 R² (0.997 R² .. 0.999 R²)
48+mean 2.439 ms (2.425 ms .. 2.456 ms)
49+std dev 47.42 μs (39.74 μs .. 62.97 μs)
50+
51+benchmarked Countdown/Put/effectful - static
52+time 555.5 μs (542.5 μs .. 567.2 μs)
53+ 0.995 R² (0.985 R² .. 1.000 R²)
54+mean 548.2 μs (544.0 μs .. 561.4 μs)
55+std dev 19.40 μs (5.420 μs .. 41.81 μs)
56+variance introduced by outliers: 12% (moderately inflated)
57+
58+benchmarked Countdown/Put/effectful - dynamic
59+time 2.729 ms (2.688 ms .. 2.777 ms)
60+ 0.998 R² (0.996 R² .. 0.999 R²)
61+mean 2.736 ms (2.722 ms .. 2.761 ms)
62+std dev 59.64 μs (42.50 μs .. 90.32 μs)
63+
64+benchmarked Countdown/Put+Exc/fused-effects
65+time 11.89 ms (11.76 ms .. 12.06 ms)
66+ 0.999 R² (0.999 R² .. 1.000 R²)
67+mean 11.93 ms (11.87 ms .. 12.05 ms)
68+std dev 199.3 μs (102.4 μs .. 324.7 μs)
69+
70+benchmarked Countdown/Put+Exc/mtl
71+time 5.196 ms (5.120 ms .. 5.299 ms)
72+ 0.998 R² (0.994 R² .. 0.999 R²)
73+mean 5.200 ms (5.169 ms .. 5.254 ms)
74+std dev 108.8 μs (69.46 μs .. 167.0 μs)
75+
76+benchmarked Countdown/Put+Exc/polysemy
77+time 29.24 ms (28.82 ms .. 29.79 ms)
78+ 0.999 R² (0.998 R² .. 1.000 R²)
79+mean 29.51 ms (29.26 ms .. 29.95 ms)
80+std dev 681.2 μs (452.7 μs .. 990.8 μs)
81+
82+benchmarked Countdown/Put+Exc/freer-simple
83+time 13.32 ms (12.65 ms .. 14.12 ms)
84+ 0.984 R² (0.974 R² .. 0.993 R²)
85+mean 11.50 ms (11.00 ms .. 11.99 ms)
86+std dev 1.209 ms (1.080 ms .. 1.435 ms)
87+variance introduced by outliers: 48% (moderately inflated)
88+
89+benchmarked Countdown/Put+Exc/extensible-effects
90+time 17.03 ms (15.01 ms .. 18.76 ms)
91+ 0.956 R² (0.928 R² .. 0.980 R²)
92+mean 13.62 ms (12.99 ms .. 14.50 ms)
93+std dev 1.750 ms (1.315 ms .. 2.083 ms)
94+variance introduced by outliers: 56% (severely inflated)
95+
96+benchmarked Countdown/Put+Exc/shallow
97+time 580.0 μs (475.1 μs .. 675.5 μs)
98+ 0.971 R² (0.958 R² .. 1.000 R²)
99+mean 573.0 μs (566.0 μs .. 584.6 μs)
100+std dev 14.90 μs (1.088 μs .. 19.80 μs)
101+
102+benchmarked Countdown/Put+Exc/effectful - static
103+time 588.1 μs (520.7 μs .. 679.1 μs)
104+ 0.974 R² (0.954 R² .. 0.998 R²)
105+mean 602.3 μs (596.0 μs .. 612.8 μs)
106+std dev 13.75 μs (5.999 μs .. 17.97 μs)
107+
108+benchmarked Countdown/Put+Exc/effectful - dynamic
109+time 2.769 ms (2.747 ms .. 2.806 ms)
110+ 0.997 R² (0.992 R² .. 1.000 R²)
111+mean 2.796 ms (2.783 ms .. 2.832 ms)
112+std dev 48.48 μs (21.03 μs .. 95.12 μs)
113+
114+benchmarked HTTP/fused-effects
115+time 1.937 ms (1.916 ms .. 1.976 ms)
116+ 0.997 R² (0.993 R² .. 1.000 R²)
117+mean 1.937 ms (1.928 ms .. 1.957 ms)
118+std dev 29.94 μs (11.47 μs .. 54.28 μs)
119+
120+benchmarked HTTP/polysemy
121+time 34.56 ms (33.19 ms .. 36.29 ms)
122+ 0.995 R² (0.992 R² .. 1.000 R²)
123+mean 33.67 ms (33.40 ms .. 34.39 ms)
124+std dev 841.1 μs (347.0 μs .. 1.492 ms)
125+
126+benchmarked HTTP/extensible-effects
127+time 19.92 ms (18.98 ms .. 21.52 ms)
128+ 0.983 R² (0.970 R² .. 0.991 R²)
129+mean 17.74 ms (16.85 ms .. 18.62 ms)
130+std dev 1.942 ms (1.676 ms .. 2.228 ms)
131+variance introduced by outliers: 48% (moderately inflated)
132+
133+benchmarked HTTP/Deep embedding
134+time 28.14 ms (25.55 ms .. 30.55 ms)
135+ 0.980 R² (0.966 R² .. 0.993 R²)
136+mean 24.73 ms (22.59 ms .. 26.22 ms)
137+std dev 3.694 ms (2.445 ms .. 4.726 ms)
138+variance introduced by outliers: 61% (severely inflated)
139+
140+benchmarking HTTP/Shallow embedding ... took 11.97 s, total 40147 iterations
141+benchmarked HTTP/Shallow embedding
142+time 22.38 μs (21.23 μs .. 23.27 μs)
143+ 0.994 R² (0.977 R² .. 0.999 R²)
144+mean 25.00 μs (24.76 μs .. 25.35 μs)
145+std dev 484.0 ns (352.7 ns .. 601.7 ns)
146+
147+benchmarked HTTP/freer-simple
148+time 19.35 ms (18.52 ms .. 20.60 ms)
149+ 0.980 R² (0.959 R² .. 0.992 R²)
150+mean 17.17 ms (16.27 ms .. 18.04 ms)
151+std dev 1.945 ms (1.653 ms .. 2.326 ms)
152+variance introduced by outliers: 45% (moderately inflated)
153+
154+benchmarking HTTP/effectful - static ... took 11.95 s, total 38223 iterations
155+benchmarked HTTP/effectful - static
156+time 25.03 μs (16.61 μs .. 35.70 μs)
157+ 0.838 R² (0.740 R² .. 0.999 R²)
158+mean 25.57 μs (24.80 μs .. 27.01 μs)
159+std dev 1.644 μs (121.0 ns .. 2.127 μs)
160+variance introduced by outliers: 18% (moderately inflated)
161+
162+benchmarked HTTP/effectful - dynamic
163+time 4.058 ms (3.662 ms .. 4.753 ms)
164+ 0.918 R² (0.847 R² .. 0.997 R²)
165+mean 3.886 ms (3.773 ms .. 4.122 ms)
166+std dev 397.4 μs (161.9 μs .. 614.5 μs)
167+variance introduced by outliers: 50% (severely inflated)
168+
169+*** Space benchmarks (these will take some time to run) ***
170+
14Countdown
171Countdown
15
172
16− Case Allocated
173+ Case Allocated GCs
17− fused-effects 40
174+ fused-effects 2,512 0
18− mtl 40
175+ mtl 792 0
19− polysemy 1,304
176+ polysemy 4,184 0
20− freer-simple 1,096
177+ freer-simple 1,120 0
21− extensible-effects 1,304
178+ extensible-effects 1,264 0
22− shallow 232
179+ shallow 232 0
180+ effectful - static 4,000,488 3
181+ effectful - dynamic 14,401,376 13
23
182
24Countdown + exc
183Countdown + exc
25
184
26− Case Allocated GCs
185+ Case Allocated GCs
27− fused-effects 336
186+ fused-effects 1,080 0
28− mtl 336
187+ mtl 608 0
29− polysemy 792
188+ polysemy 4,144 0
30− freer-simple 864
189+ freer-simple 576 0
31− extensible-effects 984
190+ extensible-effects 688 0
32− shallow 320
191+ shallow 0 0
192+ effectful - static 4,002,080 3
193+ effectful - dynamic 14,403,832 13
33```
194```
34
195
35−(The fact that `fused-effects` and `mtl` have the same allocations is not an error; `fused-effects` was designed to have almost identical performance characteristics to `mtl`.)
196+</details>
197+
198+<details>
36
199
37−Time (`State`-based countdown):
200+<summary>macOS – MacBook Pro (13-inch, 2018, Four Thunderbolt 3 Ports) – 2.3 GHz Quad-Core Intel Core i5</summary>
38
201
39```
202```
203+*** Time benchmarks ***
40benchmarked Countdown/Put/fused-effects
204benchmarked Countdown/Put/fused-effects
41−time 5.692 μs (5.570 μs .. 5.835 μs)
205+time 13.54 ms (13.44 ms .. 13.67 ms)
206+ 0.999 R² (0.998 R² .. 1.000 R²)
207+mean 13.58 ms (13.54 ms .. 13.69 ms)
208+std dev 165.6 μs (94.38 μs .. 276.3 μs)
42
209
43benchmarked Countdown/Put/mtl
210benchmarked Countdown/Put/mtl
44−time 5.500 μs (5.386 μs .. 5.719 μs)
211+time 4.885 ms (4.777 ms .. 4.954 ms)
212+ 0.998 R² (0.993 R² .. 1.000 R²)
213+mean 4.995 ms (4.934 ms .. 5.227 ms)
214+std dev 333.6 μs (54.64 μs .. 696.6 μs)
215+variance introduced by outliers: 37% (moderately inflated)
45
216
46benchmarked Countdown/Put/polysemy
217benchmarked Countdown/Put/polysemy
47−time 1.903 ms (1.845 ms .. 1.954 ms)
218+time 20.82 ms (20.58 ms .. 21.10 ms)
219+ 0.999 R² (0.997 R² .. 1.000 R²)
220+mean 20.82 ms (20.70 ms .. 21.00 ms)
221+std dev 359.1 μs (243.7 μs .. 578.8 μs)
48
222
49benchmarked Countdown/Put/freer-simple
223benchmarked Countdown/Put/freer-simple
50−time 1.324 ms (1.282 ms .. 1.361 ms)
224+time 20.18 ms (19.82 ms .. 20.56 ms)
225+ 0.998 R² (0.997 R² .. 0.999 R²)
226+mean 19.90 ms (19.56 ms .. 20.53 ms)
227+std dev 1.084 ms (524.8 μs .. 2.078 ms)
228+variance introduced by outliers: 22% (moderately inflated)
51
229
52benchmarked Countdown/Put/extensible-effects
230benchmarked Countdown/Put/extensible-effects
53−time 1.383 ms (1.343 ms .. 1.422 ms)
231+time 22.01 ms (21.29 ms .. 22.72 ms)
232+ 0.997 R² (0.995 R² .. 0.999 R²)
233+mean 20.74 ms (19.73 ms .. 21.26 ms)
234+std dev 1.554 ms (611.3 μs .. 2.309 ms)
235+variance introduced by outliers: 30% (moderately inflated)
54
236
55benchmarked Countdown/Put/shallow
237benchmarked Countdown/Put/shallow
56−time 275.1 μs (270.1 μs .. 281.6 μs)
238+time 2.432 ms (2.390 ms .. 2.477 ms)
57−```
239+ 0.998 R² (0.997 R² .. 0.999 R²)
58−
240+mean 2.439 ms (2.425 ms .. 2.456 ms)
59−Time (`State` + `Error` countdown):
241+std dev 47.42 μs (39.74 μs .. 62.97 μs)
242+
243+benchmarked Countdown/Put/effectful - static
244+time 555.5 μs (542.5 μs .. 567.2 μs)
245+ 0.995 R² (0.985 R² .. 1.000 R²)
246+mean 548.2 μs (544.0 μs .. 561.4 μs)
247+std dev 19.40 μs (5.420 μs .. 41.81 μs)
248+variance introduced by outliers: 12% (moderately inflated)
249+
250+benchmarked Countdown/Put/effectful - dynamic
251+time 2.729 ms (2.688 ms .. 2.777 ms)
252+ 0.998 R² (0.996 R² .. 0.999 R²)
253+mean 2.736 ms (2.722 ms .. 2.761 ms)
254+std dev 59.64 μs (42.50 μs .. 90.32 μs)
60
255
61−```
62benchmarked Countdown/Put+Exc/fused-effects
256benchmarked Countdown/Put+Exc/fused-effects
63−time 9.829 μs (9.645 μs .. 10.04 μs)
257+time 11.89 ms (11.76 ms .. 12.06 ms)
258+ 0.999 R² (0.999 R² .. 1.000 R²)
259+mean 11.93 ms (11.87 ms .. 12.05 ms)
260+std dev 199.3 μs (102.4 μs .. 324.7 μs)
64
261
65benchmarked Countdown/Put+Exc/mtl
262benchmarked Countdown/Put+Exc/mtl
66−time 9.968 μs (9.779 μs .. 10.15 μs)
263+time 5.196 ms (5.120 ms .. 5.299 ms)
264+ 0.998 R² (0.994 R² .. 0.999 R²)
265+mean 5.200 ms (5.169 ms .. 5.254 ms)
266+std dev 108.8 μs (69.46 μs .. 167.0 μs)
67
267
68benchmarked Countdown/Put+Exc/polysemy
268benchmarked Countdown/Put+Exc/polysemy
69−time 418.1 μs (408.9 μs .. 427.1 μs)
269+time 29.24 ms (28.82 ms .. 29.79 ms)
270+ 0.999 R² (0.998 R² .. 1.000 R²)
271+mean 29.51 ms (29.26 ms .. 29.95 ms)
272+std dev 681.2 μs (452.7 μs .. 990.8 μs)
70
273
71benchmarked Countdown/Put+Exc/freer-simple
274benchmarked Countdown/Put+Exc/freer-simple
72−time 1.157 ms (1.120 ms .. 1.199 ms)
275+time 13.32 ms (12.65 ms .. 14.12 ms)
276+ 0.984 R² (0.974 R² .. 0.993 R²)
277+mean 11.50 ms (11.00 ms .. 11.99 ms)
278+std dev 1.209 ms (1.080 ms .. 1.435 ms)
279+variance introduced by outliers: 48% (moderately inflated)
73
280
74benchmarked Countdown/Put+Exc/extensible-effects
281benchmarked Countdown/Put+Exc/extensible-effects
75−time 1.232 ms (1.212 ms .. 1.262 ms)
282+time 17.03 ms (15.01 ms .. 18.76 ms)
283+ 0.956 R² (0.928 R² .. 0.980 R²)
284+mean 13.62 ms (12.99 ms .. 14.50 ms)
285+std dev 1.750 ms (1.315 ms .. 2.083 ms)
286+variance introduced by outliers: 56% (severely inflated)
76
287
77benchmarked Countdown/Put+Exc/shallow
288benchmarked Countdown/Put+Exc/shallow
78−time 55.12 μs (54.34 μs .. 56.29 μs)
289+time 580.0 μs (475.1 μs .. 675.5 μs)
79−```
290+ 0.971 R² (0.958 R² .. 1.000 R²)
80−
291+mean 573.0 μs (566.0 μs .. 584.6 μs)
81−Time (custom HTTP DSL):
292+std dev 14.90 μs (1.088 μs .. 19.80 μs)
293+
294+benchmarked Countdown/Put+Exc/effectful - static
295+time 588.1 μs (520.7 μs .. 679.1 μs)
296+ 0.974 R² (0.954 R² .. 0.998 R²)
297+mean 602.3 μs (596.0 μs .. 612.8 μs)
298+std dev 13.75 μs (5.999 μs .. 17.97 μs)
299+
300+benchmarked Countdown/Put+Exc/effectful - dynamic
301+time 2.769 ms (2.747 ms .. 2.806 ms)
302+ 0.997 R² (0.992 R² .. 1.000 R²)
303+mean 2.796 ms (2.783 ms .. 2.832 ms)
304+std dev 48.48 μs (21.03 μs .. 95.12 μs)
82
305
83−```
84benchmarked HTTP/fused-effects
306benchmarked HTTP/fused-effects
85−time 8.311 μs (8.060 μs .. 8.592 μs)
307+time 1.937 ms (1.916 ms .. 1.976 ms)
308+ 0.997 R² (0.993 R² .. 1.000 R²)
309+mean 1.937 ms (1.928 ms .. 1.957 ms)
310+std dev 29.94 μs (11.47 μs .. 54.28 μs)
86
311
87benchmarked HTTP/polysemy
312benchmarked HTTP/polysemy
88−time 14.99 ms (14.26 ms .. 15.80 ms)
313+time 34.56 ms (33.19 ms .. 36.29 ms)
314+ 0.995 R² (0.992 R² .. 1.000 R²)
315+mean 33.67 ms (33.40 ms .. 34.39 ms)
316+std dev 841.1 μs (347.0 μs .. 1.492 ms)
89
317
90benchmarked HTTP/extensible-effects
318benchmarked HTTP/extensible-effects
91−time 1.612 ms (1.578 ms .. 1.654 ms)
319+time 19.92 ms (18.98 ms .. 21.52 ms)
320+ 0.983 R² (0.970 R² .. 0.991 R²)
321+mean 17.74 ms (16.85 ms .. 18.62 ms)
322+std dev 1.942 ms (1.676 ms .. 2.228 ms)
323+variance introduced by outliers: 48% (moderately inflated)
92
324
93benchmarked HTTP/Deep embedding
325benchmarked HTTP/Deep embedding
94−time 2.027 ms (1.876 ms .. 2.184 ms)
326+time 28.14 ms (25.55 ms .. 30.55 ms)
327+ 0.980 R² (0.966 R² .. 0.993 R²)
328+mean 24.73 ms (22.59 ms .. 26.22 ms)
329+std dev 3.694 ms (2.445 ms .. 4.726 ms)
330+variance introduced by outliers: 61% (severely inflated)
95
331
332+benchmarking HTTP/Shallow embedding ... took 11.97 s, total 40147 iterations
96benchmarked HTTP/Shallow embedding
333benchmarked HTTP/Shallow embedding
97−time 15.94 μs (15.49 μs .. 16.46 μs)
334+time 22.38 μs (21.23 μs .. 23.27 μs)
335+ 0.994 R² (0.977 R² .. 0.999 R²)
336+mean 25.00 μs (24.76 μs .. 25.35 μs)
337+std dev 484.0 ns (352.7 ns .. 601.7 ns)
98
338
99benchmarked HTTP/freer-simple
339benchmarked HTTP/freer-simple
100−time 1.478 ms (1.443 ms .. 1.515 ms)
340+time 19.35 ms (18.52 ms .. 20.60 ms)
341+ 0.980 R² (0.959 R² .. 0.992 R²)
342+mean 17.17 ms (16.27 ms .. 18.04 ms)
343+std dev 1.945 ms (1.653 ms .. 2.326 ms)
344+variance introduced by outliers: 45% (moderately inflated)
345+
346+benchmarking HTTP/effectful - static ... took 11.95 s, total 38223 iterations
347+benchmarked HTTP/effectful - static
348+time 25.03 μs (16.61 μs .. 35.70 μs)
349+ 0.838 R² (0.740 R² .. 0.999 R²)
350+mean 25.57 μs (24.80 μs .. 27.01 μs)
351+std dev 1.644 μs (121.0 ns .. 2.127 μs)
352+variance introduced by outliers: 18% (moderately inflated)
353+
354+benchmarked HTTP/effectful - dynamic
355+time 4.058 ms (3.662 ms .. 4.753 ms)
356+ 0.918 R² (0.847 R² .. 0.997 R²)
357+mean 3.886 ms (3.773 ms .. 4.122 ms)
358+std dev 397.4 μs (161.9 μs .. 614.5 μs)
359+variance introduced by outliers: 50% (severely inflated)
360+
361+*** Space benchmarks (these will take some time to run) ***
362+
363+Countdown
364+
365+ Case Allocated GCs
366+ fused-effects 2,512 0
367+ mtl 792 0
368+ polysemy 4,184 0
369+ freer-simple 1,120 0
370+ extensible-effects 1,264 0
371+ shallow 232 0
372+ effectful - static 4,000,488 3
373+ effectful - dynamic 14,401,376 13
374+
375+Countdown + exc
376+
377+ Case Allocated GCs
378+ fused-effects 1,080 0
379+ mtl 608 0
380+ polysemy 4,144 0
381+ freer-simple 576 0
382+ extensible-effects 688 0
383+ shallow 0 0
384+ effectful - static 4,002,080 3
385+ effectful - dynamic 14,403,832 13
101```
386```
102
387
103−# Future work
388+</details>
104−* More benchmarks: `Writer`, logging, `grammar`, `pipes`.
105−* I am going to make this emit pretty graphs, or at least graphable .csv files, someday.
effects-benchmarks.cabal+10
@@ -14,6 +14,14 @@ benchmark effects-benchmarks
14 type: exitcode-stdio-1.0
14 type: exitcode-stdio-1.0
15 main-is: Main.hs
15 main-is: Main.hs
16 other-modules:
16 other-modules:
17+ Effectful.Dynamic.Bench
18+ Effectful.Dynamic.HTTP
19+ Effectful.Dynamic.Stateful
20+ Effectful.Dynamic.StatefulExcept
21+ Effectful.Static.Bench
22+ Effectful.Static.HTTP
23+ Effectful.Static.Stateful
24+ Effectful.Static.StatefulExcept
17 ExtEff.Bench
25 ExtEff.Bench
18 ExtEff.HTTP
26 ExtEff.HTTP
19 ExtEff.Stateful
27 ExtEff.Stateful
@@ -62,6 +70,8 @@ benchmark effects-benchmarks
62 DerivingStrategies
70 DerivingStrategies
63 build-depends:
71 build-depends:
64 base
72 base
73+ , effectful
74+ , effectful-core
65 , extensible-effects
75 , extensible-effects
66 , freer-simple
76 , freer-simple
67 , fused-effects
77 , fused-effects
instances/Effectful/Dynamic/Bench.hsnew file+18
@@ -0,0 +1,18 @@
1+module Effectful.Dynamic.Bench where
2+
3+import Effectful
4+import Effectful.Dynamic.HTTP
5+import Effectful.Dynamic.Stateful
6+import Effectful.Dynamic.StatefulExcept
7+import Effectful.Error.Dynamic
8+import Effectful.State.Dynamic
9+import GHC.Stack (CallStack)
10+
11+countDownBench :: Int -> (Int, Int)
12+countDownBench start = runPureEff . runLocalState start $ countDownPut
13+
14+countDownExcBench :: Int -> Either (CallStack, String) (Int, Int)
15+countDownExcBench start = runPureEff . runError . runLocalState start $ countDownExc
16+
17+httpBench :: Int -> IO Int
18+httpBench n = runEff $ runHTTP (doHTTP n)
instances/Effectful/Dynamic/HTTP.hsnew file+39
@@ -0,0 +1,39 @@
1+module Effectful.Dynamic.HTTP where
2+
3+import Control.Monad
4+import Data.Kind
5+import Effectful
6+import Effectful.Dispatch.Static
7+import Effectful.Internal.Monad
8+
9+data HTTP :: Effect where
10+ Open :: String -> HTTP m ()
11+ Close :: HTTP m ()
12+ Post :: String -> HTTP m String
13+ Get :: HTTP m String
14+
15+runHTTP :: Eff (HTTP : es) a -> Eff es a
16+runHTTP = interpret $ \_ -> \case
17+ Open _ -> pure ()
18+ Close -> pure ()
19+ Post a -> pure ("posted" <> a)
20+ Get -> pure "gotten"
21+
22+open :: HTTP :> es => String -> Eff es ()
23+open = send . Open
24+
25+close :: HTTP :> es => Eff es ()
26+close = send Close
27+
28+post :: HTTP :> es => String -> Eff es String
29+post = send . Post
30+
31+get :: HTTP :> es => Eff es String
32+get = send Get
33+
34+doHTTP :: HTTP :> es => Int -> Eff es Int
35+doHTTP n = do
36+ open "cats"
37+ replicateM_ n (get *> post "cats")
38+ close
39+ pure n
instances/Effectful/Dynamic/Stateful.hsnew file+7
@@ -0,0 +1,7 @@
1+module Effectful.Dynamic.Stateful where
2+
3+import Effectful
4+import Effectful.State.Dynamic
5+
6+countDownPut :: State Int :> es => Eff es Int
7+countDownPut = get >>= (\n -> if n < 0 then pure n else put (n - 1) *> countDownPut)
instances/Effectful/Dynamic/StatefulExcept.hsnew file+10
@@ -0,0 +1,10 @@
1+module Effectful.Dynamic.StatefulExcept where
2+
3+import Effectful
4+import Effectful.Error.Dynamic
5+import Effectful.State.Dynamic
6+
7+countDownExc :: (State Int :> es, Error String :> es) => Eff es b
8+countDownExc = go
9+ where
10+ go = get @Int >>= (\n -> if n <= 0 then throwError "what" else put @Int (n - 1) *> go)
instances/Effectful/Static/Bench.hsnew file+17
@@ -0,0 +1,17 @@
1+module Effectful.Static.Bench where
2+
3+import Effectful
4+import Effectful.Error
5+import Effectful.State.Local
6+import Effectful.Static.HTTP
7+import Effectful.Static.Stateful
8+import Effectful.Static.StatefulExcept
9+
10+countDownBench :: Int -> (Int, Int)
11+countDownBench start = runPureEff . runState start $ countDownPut
12+
13+countDownExcBench :: Int -> Either (CallStack, String) (Int, Int)
14+countDownExcBench start = runPureEff . runError . runState start $ countDownExc
15+
16+httpBench :: Int -> IO Int
17+httpBench n = runEff $ runHTTP (doHTTP n)
instances/Effectful/Static/HTTP.hsnew file+30
@@ -0,0 +1,30 @@
1+module Effectful.Static.HTTP where
2+
3+import Control.Monad
4+import Data.Kind
5+import Effectful
6+import Effectful.Dispatch.Static
7+
8+data HTTP (m :: Type -> Type) r = HTTP
9+
10+runHTTP :: Eff (HTTP : es) a -> Eff es a
11+runHTTP = evalData (DataA HTTP)
12+
13+open :: HTTP :> es => String -> Eff es ()
14+open _ = pure ()
15+
16+close :: HTTP :> es => Eff es ()
17+close = pure ()
18+
19+post :: HTTP :> es => String -> Eff es String
20+post a = pure ("posted" <> a)
21+
22+get :: HTTP :> es => Eff es String
23+get = pure "gotten"
24+
25+doHTTP :: HTTP :> es => Int -> Eff es Int
26+doHTTP n = do
27+ open "cats"
28+ replicateM_ n (get *> post "cats")
29+ close
30+ pure n
instances/Effectful/Static/Stateful.hsnew file+7
@@ -0,0 +1,7 @@
1+module Effectful.Static.Stateful where
2+
3+import Effectful
4+import Effectful.State.Local
5+
6+countDownPut :: State Int :> es => Eff es Int
7+countDownPut = get >>= (\n -> if n < 0 then pure n else put (n - 1) *> countDownPut)
instances/Effectful/Static/StatefulExcept.hsnew file+10
@@ -0,0 +1,10 @@
1+module Effectful.Static.StatefulExcept where
2+
3+import Effectful
4+import Effectful.Error
5+import Effectful.State.Local
6+
7+countDownExc :: (State Int :> es, Error String :> es) => Eff es b
8+countDownExc = go
9+ where
10+ go = get @Int >>= (\n -> if n <= 0 then throwError "what" else put @Int (n - 1) *> go)
instances/ExtEff/HTTP.hs+6−8
@@ -5,24 +5,22 @@ import Control.Eff.Extend
5import Control.Monad
5import Control.Monad
6import Data.Function
6import Data.Function
7
7
8−type HttpM = Eff '[HTTP, Lift IO]
9−
10data HTTP a where
8data HTTP a where
11 Open :: String -> HTTP ()
9 Open :: String -> HTTP ()
12 Close :: HTTP ()
10 Close :: HTTP ()
13 Post :: String -> HTTP String
11 Post :: String -> HTTP String
14 HGet :: HTTP String
12 HGet :: HTTP String
15
13
16−open' :: String -> HttpM ()
14+open' :: Member HTTP e => String -> Eff e ()
17open' = send . Open
15open' = send . Open
18
16
19−close' :: HttpM ()
17+close' :: Member HTTP e => Eff e ()
20close' = send Close
18close' = send Close
21
19
22−post' :: String -> HttpM String
20+post' :: Member HTTP e => String -> Eff e String
23post' = send . Post
21post' = send . Post
24
22
25−get' :: HttpM String
23+get' :: Member HTTP e => Eff e String
26get' = send HGet
24get' = send HGet
27
25
28instance Handle HTTP r b (Eff e b) where
26instance Handle HTTP r b (Eff e b) where
@@ -35,10 +33,10 @@ instance Handle HTTP r b (Eff e b) where
35doHttp :: Eff (HTTP ': e) b -> Eff e b
33doHttp :: Eff (HTTP ': e) b -> Eff e b
36doHttp = fix (handle_relay pure)
34doHttp = fix (handle_relay pure)
37
35
38−runHttp :: HttpM a -> IO a
36+runHttp :: Eff '[HTTP, Lift IO] a -> IO a
39runHttp = runLift . doHttp
37runHttp = runLift . doHttp
40
38
41−doHTTP :: Int -> Eff '[HTTP, Lift IO] Int
39+doHTTP :: Member HTTP e => Int -> Eff e Int
42doHTTP n = do
40doHTTP n = do
43 open' "cats"
41 open' "cats"
44 replicateM_ n (get' *> post' "cats")
42 replicateM_ n (get' *> post' "cats")
instances/Freer/HTTP.hs+6−8
@@ -3,24 +3,22 @@ module Freer.HTTP where
3import Control.Monad
3import Control.Monad
4import Control.Monad.Freer
4import Control.Monad.Freer
5
5
6−type HttpM = Eff '[HTTP, IO]
7−
8data HTTP a where
6data HTTP a where
9 Open :: String -> HTTP ()
7 Open :: String -> HTTP ()
10 Close :: HTTP ()
8 Close :: HTTP ()
11 Post :: String -> HTTP String
9 Post :: String -> HTTP String
12 HGet :: HTTP String
10 HGet :: HTTP String
13
11
14−open' :: String -> HttpM ()
12+open' :: Member HTTP e => String -> Eff e ()
15open' = send . Open
13open' = send . Open
16
14
17−close' :: HttpM ()
15+close' :: Member HTTP e => Eff e ()
18close' = send Close
16close' = send Close
19
17
20−post' :: String -> HttpM String
18+post' :: Member HTTP e => String -> Eff e String
21post' = send . Post
19post' = send . Post
22
20
23−get' :: HttpM String
21+get' :: Member HTTP e => Eff e String
24get' = send HGet
22get' = send HGet
25
23
26doHttp :: Eff (HTTP ': e) b -> Eff e b
24doHttp :: Eff (HTTP ': e) b -> Eff e b
@@ -33,10 +31,10 @@ doHttp =
33 HGet -> pure "gotten"
31 HGet -> pure "gotten"
34 )
32 )
35
33
36−runHttp :: HttpM a -> IO a
34+runHttp :: Eff '[HTTP, IO] a -> IO a
37runHttp = runM . doHttp
35runHttp = runM . doHttp
38
36
39−doHTTP :: Int -> Eff '[HTTP, IO] Int
37+doHTTP :: Member HTTP e => Int -> Eff e Int
40doHTTP n = do
38doHTTP n = do
41 open' "cats"
39 open' "cats"
42 replicateM_ n (get' *> post' "cats")
40 replicateM_ n (get' *> post' "cats")
instances/Freer/StatefulExcept.hs+1−1
@@ -4,7 +4,7 @@ import Control.Monad.Freer
4import Control.Monad.Freer.Error
4import Control.Monad.Freer.Error
5import Control.Monad.Freer.State
5import Control.Monad.Freer.State
6
6
7−countDownExc :: Eff '[State Int, Error String] b
7+countDownExc :: (Member (State Int) e, Member (Error String) e) => Eff e b
8countDownExc = go
8countDownExc = go
9 where
9 where
10 go = get @Int >>= (\n -> if n <= 0 then throwError "what" else put @Int (n - 1) *> go)
10 go = get @Int >>= (\n -> if n <= 0 then throwError "what" else put @Int (n - 1) *> go)
instances/Fused/HTTP.hs+6−8
@@ -16,20 +16,18 @@ data HTTP (m :: * -> *) k where
16 Post :: String -> HTTP m String
16 Post :: String -> HTTP m String
17 HGet :: HTTP m String
17 HGet :: HTTP m String
18
18
19−open' :: String -> HttpM ()
19+open' :: Has HTTP sig m => String -> m ()
20open' s = send (Open s)
20open' s = send (Open s)
21
21
22−close' :: HttpM ()
22+close' :: Has HTTP sig m => m ()
23close' = send Close
23close' = send Close
24
24
25−post' :: String -> HttpM String
25+post' :: Has HTTP sig m => String -> m String
26post' s = send (Post s)
26post' s = send (Post s)
27
27
28−get' :: HttpM String
28+get' :: Has HTTP sig m => m String
29get' = send HGet
29get' = send HGet
30
30
31−type HttpM = HttpC (LiftC IO)
32−
33instance (Algebra sig m) => Algebra (HTTP :+: sig) (HttpC m) where
31instance (Algebra sig m) => Algebra (HTTP :+: sig) (HttpC m) where
34 alg hdl (L act) ctx = case act of
32 alg hdl (L act) ctx = case act of
35 Open _ -> pure ctx
33 Open _ -> pure ctx
@@ -38,10 +36,10 @@ instance (Algebra sig m) => Algebra (HTTP :+: sig) (HttpC m) where
38 HGet -> pure $ ctx $> "lmao"
36 HGet -> pure $ ctx $> "lmao"
39 alg hdl (R other) ctx = HttpC (alg (runHttpC . hdl) other ctx)
37 alg hdl (R other) ctx = HttpC (alg (runHttpC . hdl) other ctx)
40
38
41−runHttp :: HttpM a -> IO a
39+runHttp :: HttpC (LiftC IO) a -> IO a
42runHttp = runM . runHttpC
40runHttp = runM . runHttpC
43
41
44−doHTTP :: Int -> HttpC (LiftC IO) Int
42+doHTTP :: Has HTTP sig m => Int -> m Int
45doHTTP n = do
43doHTTP n = do
46 open' "cats"
44 open' "cats"
47 replicateM_ n (get' *> post' "cats")
45 replicateM_ n (get' *> post' "cats")
instances/Poly/HTTP.hs+5−5
@@ -15,16 +15,16 @@ data Http (m :: * -> *) a where
15
15
16makeSem ''Http
16makeSem ''Http
17
17
18−open' :: String -> HttpM ()
18+open' :: Member Http r => String -> Sem r ()
19open' = hOpen
19open' = hOpen
20
20
21−close' :: HttpM ()
21+close' :: Member Http r => Sem r ()
22close' = hClose
22close' = hClose
23
23
24−post' :: String -> HttpM String
24+post' :: Member Http r => String -> Sem r String
25post' = hPost
25post' = hPost
26
26
27−get' :: HttpM String
27+get' :: Member Http r => Sem r String
28get' = hGet
28get' = hGet
29
29
30runHttp' :: Sem (Http ': r) a -> Sem r a
30runHttp' :: Sem (Http ': r) a -> Sem r a
@@ -37,7 +37,7 @@ runHttp' = interpret $ \case
37runHttp :: HttpM a -> IO a
37runHttp :: HttpM a -> IO a
38runHttp = runFinal . runHttp'
38runHttp = runFinal . runHttp'
39
39
40−doHTTP :: Int -> Sem '[Http, Final IO] Int
40+doHTTP :: Member Http r => Int -> Sem r Int
41doHTTP n = do
41doHTTP n = do
42 open' "cats"
42 open' "cats"
43 replicateM_ n (get' *> post' "cats")
43 replicateM_ n (get' *> post' "cats")
package.yaml+2
@@ -12,6 +12,8 @@ benchmarks:
12 - extensible-effects
12 - extensible-effects
13 - gauge
13 - gauge
14 - weigh
14 - weigh
15+ - effectful
16+ - effectful-core
15 source-dirs:
17 source-dirs:
16 - instances
18 - instances
17 - src
19 - src
src/Main.hs+17−5
@@ -4,6 +4,8 @@
4
4
5module Main where
5module Main where
6
6
7+import qualified Effectful.Dynamic.Bench as EffectfulDynamic
8+import qualified Effectful.Static.Bench as EffectfulStatic
7import qualified ExtEff.Bench as ExtEff
9import qualified ExtEff.Bench as ExtEff
8import qualified Freer.Bench as Freer
10import qualified Freer.Bench as Freer
9import qualified Fused.Bench as Fused
11import qualified Fused.Bench as Fused
@@ -33,7 +35,9 @@ main = do
33 bench "polysemy" (nf Poly.countDownBench runs),
35 bench "polysemy" (nf Poly.countDownBench runs),
34 bench "freer-simple" (nf Freer.countDownBench runs),
36 bench "freer-simple" (nf Freer.countDownBench runs),
35 bench "extensible-effects" (nf ExtEff.countDownBench runs),
37 bench "extensible-effects" (nf ExtEff.countDownBench runs),
36− bench "shallow" (nf Shallow.countDownBench runs)
38+ bench "shallow" (nf Shallow.countDownBench runs),
39+ bench "effectful - static" (nf EffectfulStatic.countDownBench runs),
40+ bench "effectful - dynamic" (nf EffectfulDynamic.countDownBench runs)
37 ],
41 ],
38 bgroup
42 bgroup
39 "Put+Exc"
43 "Put+Exc"
@@ -42,7 +46,9 @@ main = do
42 bench "polysemy" (nf Poly.countDownExcBench runs),
46 bench "polysemy" (nf Poly.countDownExcBench runs),
43 bench "freer-simple" (nf Freer.countDownExcBench runs),
47 bench "freer-simple" (nf Freer.countDownExcBench runs),
44 bench "extensible-effects" (nf ExtEff.countDownExcBench runs),
48 bench "extensible-effects" (nf ExtEff.countDownExcBench runs),
45− bench "shallow" (nf Shallow.countDownExcBench runs)
49+ bench "shallow" (nf Shallow.countDownExcBench runs),
50+ bench "effectful - static" (nf EffectfulStatic.countDownExcBench runs),
51+ bench "effectful - dynamic" (nf EffectfulDynamic.countDownExcBench runs)
46 ]
52 ]
47 ],
53 ],
48 bgroup
54 bgroup
@@ -52,7 +58,9 @@ main = do
52 bench "extensible-effects" (nfAppIO ExtEff.httpBench runs),
58 bench "extensible-effects" (nfAppIO ExtEff.httpBench runs),
53 bench "Deep embedding" (nfAppIO MTL.httpBench runs),
59 bench "Deep embedding" (nfAppIO MTL.httpBench runs),
54 bench "Shallow embedding" (nfAppIO Shallow.httpBench runs),
60 bench "Shallow embedding" (nfAppIO Shallow.httpBench runs),
55− bench "freer-simple" (nfAppIO Freer.httpBench runs)
61+ bench "freer-simple" (nfAppIO Freer.httpBench runs),
62+ bench "effectful - static" (nfAppIO EffectfulStatic.httpBench runs),
63+ bench "effectful - dynamic" (nfAppIO EffectfulDynamic.httpBench runs)
56 ]
64 ]
57 ]
65 ]
58
66
@@ -65,7 +73,9 @@ main = do
65 Weigh.func "polysemy" Poly.countDownBench wruns,
73 Weigh.func "polysemy" Poly.countDownBench wruns,
66 Weigh.func "freer-simple" Freer.countDownBench wruns,
74 Weigh.func "freer-simple" Freer.countDownBench wruns,
67 Weigh.func "extensible-effects" ExtEff.countDownBench wruns,
75 Weigh.func "extensible-effects" ExtEff.countDownBench wruns,
68− Weigh.func "shallow" Shallow.countDownBench wruns
76+ Weigh.func "shallow" Shallow.countDownBench wruns,
77+ Weigh.func "effectful - static" EffectfulStatic.countDownBench runs,
78+ Weigh.func "effectful - dynamic" EffectfulDynamic.countDownBench runs
69 ]
79 ]
70 Weigh.wgroup "Countdown + exc" $
80 Weigh.wgroup "Countdown + exc" $
71 sequence_
81 sequence_
@@ -74,5 +84,7 @@ main = do
74 Weigh.func "polysemy" Poly.countDownExcBench wruns,
84 Weigh.func "polysemy" Poly.countDownExcBench wruns,
75 Weigh.func "freer-simple" Freer.countDownExcBench wruns,
85 Weigh.func "freer-simple" Freer.countDownExcBench wruns,
76 Weigh.func "extensible-effects" ExtEff.countDownExcBench wruns,
86 Weigh.func "extensible-effects" ExtEff.countDownExcBench wruns,
77− Weigh.func "shallow" Shallow.countDownExcBench wruns
87+ Weigh.func "shallow" Shallow.countDownExcBench wruns,
88+ Weigh.func "effectful - static" EffectfulStatic.countDownExcBench runs,
89+ Weigh.func "effectful - dynamic" EffectfulDynamic.countDownExcBench runs
78 ]
90 ]
stack.yaml+7
@@ -41,6 +41,13 @@ packages:
41#
41#
42extra-deps:
42extra-deps:
43 - fused-effects-1.1.1.1
43 - fused-effects-1.1.1.1
44+ - git: https://github.com/arybczak/effectful.git
45+ commit: 0d0283948ddd3204f69cdc60871978efe21452ae
46+ subdir: effectful
47+ - git: https://github.com/arybczak/effectful.git
48+ commit: 0d0283948ddd3204f69cdc60871978efe21452ae
49+ subdir: effectful-core
50+
44# Override default flag values for local packages and extra-deps
51# Override default flag values for local packages and extra-deps
45# flags: {}
52# flags: {}
46
53