bench/lang: simplify signature of the test function
[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: Root = new {classes.first}[Root]"
99 write "var b: Root = a"
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 var tagc = ""
145 if interfaces then tagc = "X"
146 write "\tRoot a = new {tagc}{classes.first}<Root>();"
147 write "\tRoot b = a;"
148 for c in classes do
149 write "\t\t\tif (a.id() > 0) a = new {tagc}{c}<Root>();"
150 end
151 write "\ttest(b, b, 10, -100);"
152 write "\ttest(a, a, {loops}, 0);"
153 write "\}"
154
155 write "static public void test(Root a, Root b, int loops, int start) \{"
156 write "\tint x = start;"
157 write "\tfor(int i = 0; i < loops; i++) \{"
158 write "\t\tfor(int j = 0; j < loops; j++) \{"
159 var test
160 if dry then test = "" else test = "a instanceof {classes[middle]} && "
161 write "\t\t\tif({test}x>=0) \{"
162 if check then write "\t\t\t\tx -= 2"
163 write "\t\t\t\} else \{ x--; a = b;\}"
164 write "\t\t}"
165 write "\t\}"
166 write "\tSystem.out.println(x);"
167 write "\}"
168 write "\}"
169 file.close
170 end
171
172 fun writecsharp(dir: String, name: String, interfaces: Bool)
173 do
174 dir = "{dir}/cs"
175 dir.mkdir
176 file = new OFStream.open("{dir}/{name}.cs")
177
178 var cl = ""
179 if interfaces then cl = "X"
180 write "class {name} \{"
181 if interfaces then
182 write "interface Root\n\t\{ int Id(); \}"
183 else
184 write "class Root\n\t\{ public int Id() \{ return 0;\} \}"
185 end
186 for c in classes do
187 if interfaces then
188 write "interface {c}<E> "
189 else
190 write "class {c}<E> "
191 end
192 if c.supers.is_empty then
193 write "\t: Root"
194 else for s in [c.supers.first] do
195 write "\t: {s}<E>"
196 end
197 if interfaces then
198 write "\{\}"
199 write "class X{c}<E> : {c}<E>"
200 end
201 write "\{"
202 write "\tpublic int Id() \{ return {c.id}; \}"
203 write "\}"
204 end
205
206 write "static void Main(string[] args) \{"
207 var tagc = ""
208 if interfaces then tagc = "X"
209 write "\tRoot a = new {tagc}{classes.first}<Root>();"
210 write "\tRoot b = a;"
211 for c in classes do
212 write "\t\t\tif (a.Id() > 0) a = new {tagc}{c}<Root>();"
213 end
214 write "\tTest(b, b, 10, -100);"
215 write "\tTest(a, a, {loops}, 0);"
216 write "\}"
217
218 write "static void Test(Root a, Root b, int loops, int start) \{"
219 write "\tint x = start;"
220 write "\tfor(int i = 0; i < loops; i++) \{"
221 write "\t\tfor(int j = 0; j < loops; j++) \{"
222 var test
223 if dry then test = "" else test = "a is {classes[middle]}<Root> && "
224 write "\t\t\tif({test}x>=0) \{"
225 if check then write "\t\t\t\tx++;"
226 write "\} else \{ x--; a = b; \};"
227 write "\t\t}"
228 write "\t\}"
229 write "\tSystem.Console.WriteLine(x);"
230 write "\}"
231 write "\}"
232 file.close
233 end
234
235 fun writescala(dir: String, name: String, interfaces: Bool)
236 do
237 dir = "{dir}/scala"
238 dir.mkdir
239 file = new OFStream.open("{dir}/{name}.scala")
240
241 var cl = ""
242 write "object {name} \{"
243 write "class Root\n\t\{ def id: Int = 0 \}"
244 for c in classes do
245 if interfaces then
246 write "trait {c}[E] "
247 else
248 write "class {c}[E] "
249 end
250 if c.supers.is_empty then
251 write "\textends Root"
252 else for s in [c.supers.first] do
253 write "\textends {s}[E]"
254 end
255 if interfaces then
256 write "\{\}"
257 write "class X{c}[E] extends {c}[E]"
258 end
259 write "\{"
260 write "\toverride def id: Int = {c.id}"
261 write "\}"
262 end
263
264 write "def main(args: Array[String]) = \{"
265 var tagc = ""
266 if interfaces then tagc = "X"
267 write "\tvar a:Root = new {tagc}{classes.first}[Root]()"
268 write "\tvar b:Root = a"
269 for c in classes do
270 write "\t\t\tif (a.id > 0) a = new {tagc}{c}[Root]();"
271 end
272 write "\ttest(b, b, 10, -100)"
273 write "\ttest(a, a, {loops}, 0)"
274 write "\}"
275
276 write "def test(aa:Root, b:Root, l: Int, start: Int) = \{"
277 write "\tvar a = aa"
278 write "\tvar x = start"
279 write "\tvar loops = l"
280 write "\tvar i = 0"
281 write "\twhile (i < loops) \{"
282 write "\t\tvar j = 0"
283 write "\t\twhile (j < loops) \{"
284 var test
285 if dry then test = "" else test = "a.isInstanceOf[{classes[middle]}[Root]] && "
286 write "\t\tif ({test}x>=0) \{"
287 if check then write "\t\t\tx += 1"
288 write "\} else \{ x = x - 1; a = b; \}"
289 write "\t\tj += 1"
290 write "\t\t\}"
291 write "\ti += 1"
292 write "\t\}"
293 write "\t\t\tprintln(x)"
294 write "\}"
295 write "\}"
296
297 file.close
298 end
299
300 fun writecpp(dir: String, name: String)
301 do
302 dir = "{dir}/cpp"
303 dir.mkdir
304 file = new OFStream.open("{dir}/{name}.cpp")
305
306 write "#include <iostream>"
307 write "#include <stdlib.h>"
308 write "class Root\n\t\{ public: virtual int id() \{ return 0;\} \};"
309 for c in classes do
310 write "template<class E>"
311 write "class {c} "
312 if c.supers.is_empty then
313 write "\t: public virtual Root"
314 else for s in [c.supers.first] do
315 write "\t: public virtual {s}<E>"
316 end
317 write "\{"
318 write "\tpublic: virtual int id() \{ return {c.id}; \}"
319 write "\};"
320 end
321
322 write "void test(Root *a, Root *b, int loops, int start) \{"
323 write "\tint x = start;"
324 write "\tfor(int i = 0; i < loops; i++) \{"
325 write "\t\tfor(int j = 0; j < loops; j++) \{"
326 var test
327 if dry then test = "" else
328 write "\t\t\t{classes[middle]}<Root> *to = dynamic_cast<{classes[middle]}<Root>*>(a);"
329 test = "to != 0 &&"
330 end
331 write "\t\tif({test}x>=0) \{"
332 if check then write "\t\t\tx += 1"
333 write "\} else \{ x--; a = b;\}"
334 write "\t\t}"
335 write "\t\}"
336 write "\tstd::cout << x << std::endl;"
337 write "\}"
338
339 write "int main(int argc, char **argv) \{"
340 write "\tRoot *a = new {classes.first}<Root>();"
341 write "\tRoot *b = a;"
342 for c in classes do
343 write "\t\t\tif (a->id() > 0) a = new {c}<Root>();"
344 end
345 write "\ttest(b, b, 10, -100);"
346 write "\ttest(a, a, {loops}, 0);"
347 write "\}"
348
349 file.close
350 end
351
352 fun writee(dir: String, name: String, se: Bool)
353 do
354 if se then
355 dir = "{dir}/se/{name}"
356 else
357 dir = "{dir}/es/{name}"
358 end
359 dir.mkdir
360 file = new OFStream.open("{dir}/root.e")
361
362 var istk = ""
363 if se then istk = " is"
364 write "class ROOT"
365 write "feature id: INTEGER {istk} do Result := 0 end"
366 write "end"
367 file.close
368
369 for c in classes do
370 file = new OFStream.open("{dir}/{c}.e")
371 write "class {c}[E] "
372 if c.supers.is_empty then
373 write "\tinherit ROOT"
374 else for s in [c.supers.first] do
375 write "\tinherit {s}[E]"
376 end
377 write "\t\tredefine id end"
378 write "feature"
379 write "\tid: INTEGER {istk} do Result := {c.id} end"
380 write "end"
381 file.close
382 end
383
384 file = new OFStream.open("{dir}/app{name}.e")
385 write "class APP{name.to_upper}"
386 if se then
387 write "insert ARGUMENTS"
388 end
389 write "create make"
390 write "feature"
391
392 if se then
393 write "\tmake{istk}"
394 else
395 write "\tmake(args: ARRAY[STRING]){istk}"
396 end
397 write "\t\tlocal"
398 write "\t\t\ta: ROOT"
399 write "\t\t\tb: ROOT"
400 write "\t\tdo"
401 write "\t\t\tcreate \{{classes.first}[ROOT]\} a"
402 write "\t\t\tb := a"
403 for c in classes do
404 write "\t\t\tif a.id > 0 then create \{{c}[ROOT]\} a end"
405 end
406 write "\t\t\ttest(b, b, 10, -100)"
407 write "\t\t\ttest(a, a, {loops}, 0)"
408 write "\t\tend"
409
410 write "\ttest(a: ROOT; b: ROOT; l: INTEGER; start: INTEGER){istk}"
411 write "\t\tlocal"
412 write "\t\t\to: ROOT"
413 write "\t\t\tto: {classes[middle]}[ROOT]"
414 write "\t\t\ti: INTEGER"
415 write "\t\t\tj: INTEGER"
416 write "\t\t\tx: INTEGER"
417 write "\t\t\tloops: INTEGER"
418 write "\t\tdo"
419 write "\t\t\to := a"
420 write "\t\t\tx := start"
421 write "\t\t\tloops := l"
422 write "\t\t\tfrom i := 0 until i>=loops loop"
423 write "\t\t\t\tfrom j := 0 until j>=loops loop"
424 var test
425 if dry then
426 test = ""
427 else
428 write "\t\t\t\t\tto ?= o"
429 test = "to /= Void and then "
430 end
431 write "\t\t\t\t\tif {test}x >= 0 then"
432 if check then write "\t\t\t\t\tx := x + 1"
433 write "\t\t\t\t\telse x := x - 1; o := b end"
434 write "\t\t\t\t\tj := j + 1"
435 write "\t\t\t\tend"
436 write "\t\t\t\ti := i + 1"
437 write "\t\t\tend"
438 write "\t\t\tprint(x.out)"
439 write "\t\tend"
440 write "end"
441 file.close
442 end
443
444 var count = false
445 end
446
447 var g = new Generator
448 var outdir = args.first
449 var name = args[1]
450 var use_interfaces = true
451 if args.length > 2 then g.dept = args[2].to_i
452 if args.length > 3 then use_interfaces = false
453
454 g.genhier
455
456 g.writenit(outdir, name)
457 g.writejava(outdir, name, use_interfaces)
458 g.writecsharp(outdir, name, use_interfaces)
459 g.writescala(outdir, name, use_interfaces)
460 g.writecpp(outdir, name)
461 g.writee(outdir, "{name}_se", true)
462 g.writee(outdir, name, false)