bench/lang: improve bench_typetest_depth
[nit.git] / benchmarks / languages / bench_typetest_depth.nit
1 #!/usr/bin/env nit
2
3 # Microbenchmak generation for multiple language
4 # Just a quick an dirty Nit script file :)
5
6 # This benchmark focuses on effects of the hierarchy dept
7 # on the typetest performances
8
9 # class Root
10 # class Klass[E] super Root
11 # class C1...CX super Root
12 # Klass[CX] isa Klass[C1]
13
14 class Klass
15 var id: Int
16 var supers = new Array[Klass]
17 var all_supers = new HashSet[Klass]
18 redef fun to_s
19 do
20 return "C{id}"
21 end
22 end
23
24 class Generator
25
26 var classes = new Array[Klass]
27
28 var dept = 5
29 var loops = 50000
30 var middle = 0
31 var dry = false
32 var check = false
33
34 fun genhier
35 do
36 var s: nullable Klass = null
37 for d in [1..dept] do
38 var c = new Klass(d)
39
40 classes.add(c)
41 c.all_supers.add(c)
42 if s != null then
43 c.supers.add(s)
44 c.all_supers.add_all(s.all_supers)
45 end
46 s = c
47 end
48 middle = (dept + 1) / 2
49 end
50
51 var file: nullable OFStream = null
52 fun write(str: String)
53 do
54 file.write(str)
55 file.write("\n")
56 end
57
58 fun writenit(dir: String, name: String)
59 do
60 dir = "{dir}/nit"
61 dir.mkdir
62 file = new OFStream.open("{dir}/{name}.nit")
63
64 write "class Root\n\tfun id: Int do return 0\nend"
65 for c in classes do
66 write "class {c}[E]"
67 if c.supers.is_empty then
68 write "\tsuper Root"
69 else for s in c.supers do
70 write "\tsuper {s}[E]"
71 end
72 write "\tredef fun id do return {c.id}"
73 write "end"
74 end
75
76 write "fun test(a,b: Root, loops, start: Int)"
77 write "do"
78 write "var x = start"
79 write "var i = 0"
80 write "while i < loops do"
81 write "\tvar j = 0"
82 write "\twhile j < loops do"
83 var test
84 if dry then test = "" else test = "a isa {classes[middle]}[Root] and "
85 write "\t\tif {test}x >= 0 then"
86 if check then write "\t\tx += 1"
87 write "\telse"
88 write "\t\t\tx -= 1"
89 write "\t\t\ta = b"
90 write "\t\tend"
91 write "\t\tj += 1"
92 write "\tend"
93 write "\ti += 1"
94 write "end"
95 write "print x"
96 write "end"
97
98 write "var a:{classes.first}[Root] = new {classes.last}[Root]"
99 write "var b:{classes.first}[Root] = new {classes.first}[Root]"
100 for c in classes do
101 write "\t\t\tif a.id > 0 then a = new {c}[Root]"
102 end
103 write "test(b, b, 10, -100)"
104 write "test(a, a, {loops}, 0)"
105
106 file.close
107 end
108
109 fun writejava(dir: String, name: String, interfaces: Bool)
110 do
111 dir = "{dir}/java"
112 dir.mkdir
113 file = new OFStream.open("{dir}/{name}.java")
114
115 var cl = ""
116 if interfaces then cl = "X"
117 write "class {name} \{"
118 if interfaces then
119 write "static interface Root\n\t\{ int id(); \}"
120 else
121 write "static class Root\n\t\{ int id() \{ return 0;\} \}"
122 end
123 for c in classes do
124 if interfaces then
125 write "static interface {c}<E> "
126 else
127 write "static class {c}<E> "
128 end
129 if c.supers.is_empty then
130 write "\textends Root"
131 else for s in [c.supers.first] do
132 write "\textends {s}<E>"
133 end
134 if interfaces then
135 write "\{\}"
136 write "static class X{c}<E> implements {c}<E>"
137 end
138 write "\{"
139 write "\tpublic int id() \{ return {c.id}; \}"
140 write "\}"
141 end
142
143 write "static public void main(String args[]) \{"
144 if interfaces then
145 write "\t{classes.first}<Root> a = new X{classes.last}<Root>();"
146 write "\t{classes.first}<Root> b = new X{classes.first}<Root>();"
147 for c in classes do
148 write "\t\t\tif (a.id() > 0) a = new X{c}<Root>();"
149 end
150 else
151 write "\t{classes.first}<Root> a = new {classes.last}<Root>();"
152 write "\t{classes.first}<Root> b = new {classes.first}<Root>();"
153 for c in classes do
154 write "\t\t\tif (a.id() > 0) a = new {c}<Root>();"
155 end
156 end
157 write "\ttest(b, b, 10, -100);"
158 write "\ttest(a, a, {loops}, 0);"
159 write "\}"
160
161 write "static public void test({classes.first}<Root> a, {classes.first}<Root> b, int loops, int start) \{"
162 write "\tint x = start;"
163 write "\tfor(int i = 0; i < loops; i++) \{"
164 write "\t\tfor(int j = 0; j < loops; j++) \{"
165 var test
166 if dry then test = "" else test = "a instanceof {classes[middle]} && "
167 write "\t\t\tif({test}x>=0) \{"
168 if check then write "\t\t\t\tx += 1"
169 write "\t\t\t\} else \{ x--; a = b;\}"
170 write "\t\t}"
171 write "\t\}"
172 write "\tSystem.out.println(x);"
173 write "\}"
174 write "\}"
175 file.close
176 end
177
178 fun writecsharp(dir: String, name: String, interfaces: Bool)
179 do
180 dir = "{dir}/cs"
181 dir.mkdir
182 file = new OFStream.open("{dir}/{name}.cs")
183
184 var cl = ""
185 if interfaces then cl = "X"
186 write "class {name} \{"
187 if interfaces then
188 write "interface Root\n\t\{ int Id(); \}"
189 else
190 write "class Root\n\t\{ public int Id() \{ return 0;\} \}"
191 end
192 for c in classes do
193 if interfaces then
194 write "interface {c}<E> "
195 else
196 write "class {c}<E> "
197 end
198 if c.supers.is_empty then
199 write "\t: Root"
200 else for s in [c.supers.first] do
201 write "\t: {s}<E>"
202 end
203 if interfaces then
204 write "\{\}"
205 write "class X{c}<E> : {c}<E>"
206 end
207 write "\{"
208 write "\tpublic int Id() \{ return {c.id}; \}"
209 write "\}"
210 end
211
212 write "static void Main(string[] args) \{"
213 if interfaces then
214 write "\t{classes.first}<Root> a = new X{classes.last}<Root>();"
215 write "\t{classes.first}<Root> b = new X{classes.first}<Root>();"
216 for c in classes do
217 write "\t\t\tif (a.Id() > 0) a = new X{c}<Root>();"
218 end
219 else
220 write "\t{classes.first}<Root> a = new {classes.last}<Root>();"
221 write "\t{classes.first}<Root> b = new {classes.first}<Root>();"
222 for c in classes do
223 write "\t\t\tif (a.Id() > 0) a = new {c}<Root>();"
224 end
225 end
226 write "\tTest(b, b, 10, -100);"
227 write "\tTest(a, a, {loops}, 0);"
228 write "\}"
229
230 write "static void Test({classes.first}<Root> a, {classes.first}<Root> b, int loops, int start) \{"
231 write "\tint x = start;"
232 write "\tfor(int i = 0; i < loops; i++) \{"
233 write "\t\tfor(int j = 0; j < loops; j++) \{"
234 var test
235 if dry then test = "" else test = "a is {classes[middle]}<Root> && "
236 write "\t\t\tif({test}x>=0) \{"
237 if check then write "\t\t\t\tx++;"
238 write "\} else \{ x--; a = b; \};"
239 write "\t\t}"
240 write "\t\}"
241 write "\tSystem.Console.WriteLine(x);"
242 write "\}"
243 write "\}"
244 file.close
245 end
246
247 fun writescala(dir: String, name: String, interfaces: Bool)
248 do
249 dir = "{dir}/scala"
250 dir.mkdir
251 file = new OFStream.open("{dir}/{name}.scala")
252
253 var cl = ""
254 write "object {name} \{"
255 write "class Root\n\t\{ def id: Int = 0 \}"
256 for c in classes do
257 if interfaces then
258 write "trait {c}[E] "
259 else
260 write "class {c}[E] "
261 end
262 if c.supers.is_empty then
263 write "\textends Root"
264 else for s in [c.supers.first] do
265 write "\textends {s}[E]"
266 end
267 if interfaces then
268 write "\{\}"
269 write "class X{c}[E] extends {c}[E]"
270 end
271 write "\{"
272 write "\toverride def id: Int = {c.id}"
273 write "\}"
274 end
275
276 write "def main(args: Array[String]) = \{"
277 if interfaces then
278 write "\tvar a:{classes.first}[Root] = new X{classes.last}[Root]()"
279 write "\tvar b:{classes.first}[Root] = new X{classes.first}[Root]()"
280 for c in classes do
281 write "\t\t\tif (a.id > 0) a = new X{c}[Root]();"
282 end
283 else
284 write "\tvar a:{classes.first}[Root] = new {classes.last}[Root]()"
285 write "\tvar b:{classes.first}[Root] = new {classes.first}[Root]()"
286 for c in classes do
287 write "\t\t\tif (a.id > 0) a = new {c}[Root]();"
288 end
289 end
290 write "\ttest(b, b, 10, -100)"
291 write "\ttest(a, a, {loops}, 0)"
292 write "\}"
293
294 write "def test(aa:{classes.first}[Root], b:{classes.first}[Root], l: Int, start: Int) = \{"
295 write "\tvar a = aa"
296 write "\tvar x = start"
297 write "\tvar loops = l"
298 write "\tvar i = 0"
299 write "\twhile (i < loops) \{"
300 write "\t\tvar j = 0"
301 write "\t\twhile (j < loops) \{"
302 var test
303 if dry then test = "" else test = "a.isInstanceOf[{classes[middle]}[Root]] && "
304 write "\t\tif ({test}x>=0) \{"
305 if check then write "\t\t\tx += 1"
306 write "\} else \{ x = x - 1; a = b; \}"
307 write "\t\tj += 1"
308 write "\t\t\}"
309 write "\ti += 1"
310 write "\t\}"
311 write "\t\t\tprintln(x)"
312 write "\}"
313 write "\}"
314
315 file.close
316 end
317
318 fun writecpp(dir: String, name: String)
319 do
320 dir = "{dir}/cpp"
321 dir.mkdir
322 file = new OFStream.open("{dir}/{name}.cpp")
323
324 write "#include <iostream>"
325 write "#include <stdlib.h>"
326 write "class Root\n\t\{ public: virtual int id() \{ return 0;\} \};"
327 for c in classes do
328 write "template<class E>"
329 write "class {c} "
330 if c.supers.is_empty then
331 write "\t: public virtual Root"
332 else for s in [c.supers.first] do
333 write "\t: public virtual {s}<E>"
334 end
335 write "\{"
336 write "\tpublic: virtual int id() \{ return {c.id}; \}"
337 write "\};"
338 end
339
340 write "void test({classes.first}<Root>* a, {classes.first}<Root>* b, int loops, int start) \{"
341 write "\tint x = start;"
342 write "\tfor(int i = 0; i < loops; i++) \{"
343 write "\t\tfor(int j = 0; j < loops; j++) \{"
344 var test
345 if dry then test = "" else
346 write "\t\t\t{classes[middle]}<Root>* to = dynamic_cast<{classes[middle]}<Root>*>(a);"
347 test = "to != 0 &&"
348 end
349 write "\t\tif({test}x>=0) \{"
350 if check then write "\t\t\tx += 1"
351 write "\} else \{ x--; a = b;\}"
352 write "\t\t}"
353 write "\t\}"
354 write "\tstd::cout << x << std::endl;"
355 write "\}"
356
357 write "int main(int argc, char **argv) \{"
358 write "\t{classes.first}<Root>* a = new {classes.last}<Root>();"
359 write "\t{classes.first}<Root>* b = new {classes.first}<Root>();"
360 for c in classes do
361 write "\t\t\tif (a->id() > 0) a = new {c}<Root>();"
362 end
363 write "\ttest(b, b, 10, -100);"
364 write "\ttest(a, a, {loops}, 0);"
365 write "\}"
366
367 file.close
368 end
369
370 fun writee(dir: String, name: String, se: Bool)
371 do
372 if se then
373 dir = "{dir}/se/{name}"
374 else
375 dir = "{dir}/es/{name}"
376 end
377 dir.mkdir
378 file = new OFStream.open("{dir}/root.e")
379
380 var istk = ""
381 if se then istk = " is"
382 write "class ROOT"
383 write "feature id: INTEGER {istk} do Result := 0 end"
384 write "end"
385 file.close
386
387 for c in classes do
388 file = new OFStream.open("{dir}/{c}.e")
389 write "class {c}[E] "
390 if c.supers.is_empty then
391 write "\tinherit ROOT"
392 else for s in [c.supers.first] do
393 write "\tinherit {s}[E]"
394 end
395 write "\t\tredefine id end"
396 write "feature"
397 write "\tid: INTEGER {istk} do Result := {c.id} end"
398 write "end"
399 file.close
400 end
401
402 file = new OFStream.open("{dir}/app{name}.e")
403 write "class APP{name.to_upper}"
404 if se then
405 write "insert ARGUMENTS"
406 end
407 write "create make"
408 write "feature"
409
410 if se then
411 write "\tmake{istk}"
412 else
413 write "\tmake(args: ARRAY[STRING]){istk}"
414 end
415 write "\t\tlocal"
416 write "\t\t\ta: {classes.first}[ROOT]"
417 write "\t\t\tb: {classes.first}[ROOT]"
418 write "\t\tdo"
419 write "\t\t\tcreate \{{classes.last}[ROOT]\} a"
420 write "\t\t\tcreate \{{classes.first}[ROOT]\} b"
421 for c in classes do
422 write "\t\t\tif a.id > 0 then create \{{c}[ROOT]\} a end"
423 end
424 write "\t\t\ttest(b, b, 10, -100)"
425 write "\t\t\ttest(a, a, {loops}, 0)"
426 write "\t\tend"
427
428 write "\ttest(a: {classes.first}[ROOT]; b: {classes.first}[ROOT]; l: INTEGER; start: INTEGER){istk}"
429 write "\t\tlocal"
430 write "\t\t\to: {classes.first}[ROOT]"
431 write "\t\t\tto: {classes[middle]}[ROOT]"
432 write "\t\t\ti: INTEGER"
433 write "\t\t\tj: INTEGER"
434 write "\t\t\tx: INTEGER"
435 write "\t\t\tloops: INTEGER"
436 write "\t\tdo"
437 write "\t\t\to := a"
438 write "\t\t\tx := start"
439 write "\t\t\tloops := l"
440 write "\t\t\tfrom i := 0 until i>=loops loop"
441 write "\t\t\t\tfrom j := 0 until j>=loops loop"
442 var test
443 if dry then
444 test = ""
445 else
446 write "\t\t\t\t\tto ?= o"
447 test = "to /= Void and then "
448 end
449 write "\t\t\t\t\tif {test}x >= 0 then"
450 if check then write "\t\t\t\t\tx := x + 1"
451 write "\t\t\t\t\telse x := x - 1; o := b end"
452 write "\t\t\t\t\tj := j + 1"
453 write "\t\t\t\tend"
454 write "\t\t\t\ti := i + 1"
455 write "\t\t\tend"
456 write "\t\t\tprint(x.out)"
457 write "\t\tend"
458 write "end"
459 file.close
460 end
461
462 var count = false
463 end
464
465 var g = new Generator
466 var outdir = args.first
467 var name = args[1]
468 var use_interfaces = true
469 if args.length > 2 then g.dept = args[2].to_i
470 if args.length > 3 then use_interfaces = false
471
472 g.genhier
473
474 g.writenit(outdir, name)
475 g.writejava(outdir, name, use_interfaces)
476 g.writecsharp(outdir, name, use_interfaces)
477 g.writescala(outdir, name, use_interfaces)
478 g.writecpp(outdir, name)
479 g.writee(outdir, "{name}_se", true)
480 g.writee(outdir, name, false)