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