2 # This file is part of NIT ( http://www.nitlanguage.org ).
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
16 # Microbenchmak generation for multiple language
17 # Just a quick an dirty Nit script file :)
19 # This benchmark focuses on effects of the hierarchy dept
20 # on the typetest performances
23 # class Klass[E] super Root
24 # class C1...CX super Root
25 # Klass[CX] isa Klass[C1]
29 var supers
= new Array[Klass]
30 var all_supers
= new HashSet[Klass]
39 var classes
= new Array[Klass]
41 var dept
= 5 is writable
42 var loops
= 50000 is writable
43 var middle
= 0 is writable
44 var dry
= false is writable
45 var check
= false is writable
48 # This is the number of distinct dynamic types for the receiver
49 var poly
= 2 is writable
51 # Use only interfaces (or traits) in the hierarchy
53 # If `false` then java&cs&scala will use classes, thus will break if MH is used
54 var use_interfaces
= true is writable
56 # Add Root0, the superclass to Root that introduce common services.
58 # This add another level of un-optimization since the services are not introduced
59 # by the static type of the receiver.
60 var use_root0
= true is writable
64 var s
: nullable Klass = null
72 c
.all_supers
.add_all
(s
.all_supers
)
79 var file
: nullable FileWriter = null
80 fun write
(str
: String)
86 fun initnit
(res
: Array[String]) do return
87 fun testnit
: String do return "true"
89 fun writenit
(dir
: String, name
: String)
91 var ia
= new Array[String]
100 file
= new FileWriter.open
("{dir}/{name}.nit")
107 write
"\tfun id: Int do return 0"
108 write
"\tvar aid: Int = id"
109 write
"\tvar next: Root is noautoinit"
110 write
"\tfun set_next(next: Root): Root do\n\t\tself.next = next\n\t\treturn next\n\tend"
113 write
"class Root\n\tsuper Root0\nend"
117 if c
.supers
.is_empty
then
119 else for s
in c
.supers
do
120 write
"\tsuper {s}[E]"
122 write
"\tredef fun id do return {c.id}"
123 write
"\tfun f{c.id}: Int do return {c.id}"
124 write
"\tvar a{c.id}: Int = {c.id}"
128 write
"fun test(a,b: Root, loops, start: Int)"
130 write
"var x = start"
131 write
"var i = loops"
132 write
"while i > 0 do"
133 write
"\tvar j = loops"
134 write
"\twhile j > 0 do"
136 if not dry
then test
= testnit
137 write
"\t\tif {test} then"
138 write
"\t\t\tvar tmp = a; a = b; b = tmp"
139 if check
then write
"\t\tx += 1"
142 write
"\t\t\ta = a.next"
143 write
"\t\t\tb = b.next"
155 write
"var b: Root = {ia.first}"
158 write
"b = b.set_next({i})"
161 write
"var a: Root = {ia.last}"
163 for i
in [1..poly
[ do
164 write
"a = a.set_next({ia[ia.length - 1 - i]})"
167 write
"test(b, b.next, 10, -100)"
168 write
"test(a, a.next, {loops}, 0)"
173 fun initjava
(res
: Array[String], interfaces
: Bool) do return
174 fun testjava
(interfaces
: Bool): String do return "true"
175 fun writejava
(dir
: String, name
: String, interfaces
: Bool)
177 var ia
= new Array[String]
178 initjava
(ia
, interfaces
)
180 print
"Java disabled"
186 file
= new FileWriter.open
("{dir}/{name}.java")
188 write
"class {name} \{"
190 if use_root0
then root0
= "Root0"
192 write
"static interface {root0} \{ long id(); Root getNext(); Root setNext(Root next); \}"
193 write
"static class XRoot implements {root0} \{"
195 write
"static class {root0} \{"
197 write
"\tpublic long id() \{ return 0;\}"
198 write
"\tpublic long aid = id();"
199 write
"\tpublic Root next;"
200 write
"\tpublic Root getNext() \{ return next;\}"
201 write
"\tpublic Root setNext(Root next) \{ this.next = next; return next; \}"
206 write
"static interface Root extends Root0 \{\}"
208 write
"static class Root extends Root0 \{\}"
214 write
"static interface {c}<E> "
216 write
"static class {c}<E> "
218 if c
.supers
.is_empty
then
219 write
"\textends Root"
220 else for s
in [c
.supers
.first
] do
221 write
"\textends {s}<E>"
225 if c
.supers
.is_empty
then
226 write
"static class X{c}<E> extends XRoot implements {c}<E>"
228 write
"static class X{c}<E> extends X{c.supers.first}<E> implements {c}<E>"
232 write
"\tpublic long id() \{ return {c.id}; \}"
233 write
"\tpublic long f{c.id}() \{ return {c.id}; \}"
234 write
"\tpublic long a{c.id} = {c.id};"
238 write
"static public void main(String args[]) \{"
239 write
"\tRoot b = {ia.first};"
240 write
"\tRoot tmp = b;"
242 write
"\tb = b.setNext({i});"
244 write
"\tb.setNext(tmp);"
245 write
"\tRoot a = {ia.last};"
247 for i
in [1..poly
[ do
248 write
"\ta = a.setNext({ia[ia.length - 1 - i]});"
250 write
"\ta.setNext(tmp);"
251 write
"\ttest(b, b.getNext(), 10, -100);"
252 write
"\ttest(a, a.getNext(), {loops}, 0);"
255 write
"static public void test(Root a, Root b, long loops, long start) \{"
256 write
"\tlong x = start;"
257 write
"\tfor(long i = loops; i > 0; i--) \{"
258 write
"\t\tfor(long j = loops; j > 0; j--) \{"
260 if not dry
then test
= testjava
(interfaces
)
261 write
"\t\t\tif({test}) \{"
262 write
"\t\t\t\tRoot tmp = a; a = b; b = tmp;"
263 if check
then write
"\t\t\t\tx = x + 1;"
264 write
"\t\t\t\} else \{ x++; a = a.getNext(); b = b.getNext(); \}"
266 write
"\t\tx++; a = a.getNext(); b = b.getNext();"
268 write
"\tSystem.out.println(x);"
274 fun initcsharp
(res
: Array[String], interfaces
: Bool) do return
275 fun testcsharp
(interfaces
: Bool): String do return "true"
276 fun writecsharp
(dir
: String, name
: String, interfaces
: Bool)
278 var ia
= new Array[String]
279 initcsharp
(ia
, interfaces
)
287 file
= new FileWriter.open
("{dir}/{name}.cs")
289 write
"class {name} \{"
291 if use_root0
then root0
= "Root0"
293 write
"interface {root0} \{ long Id(); Root GetNext(); Root SetNext(Root next); \}"
294 write
"class XRoot: {root0} \{ "
296 write
"class {root0}\n\t\{ "
298 write
"\tvirtual public long Id() \{ return 0; \}"
299 write
"\tpublic long aid;"
300 write
"\tpublic Root next;"
301 write
"\tvirtual public Root GetNext() \{ return next; \}"
302 write
"\tvirtual public Root SetNext(Root next) \{ this.next = next; return next; \}"
307 write
"interface Root: Root0 \{\}"
309 write
"class Root: Root0 \{\}"
316 write
"interface {c}<out E> "
319 write
"class {c}<E> "
322 if c
.supers
.is_empty
then
324 else for s
in [c
.supers
.first
] do
329 if c
.supers
.is_empty
then
330 write
"class X{c}<E>: XRoot, {c}<E>"
332 write
"class X{c}<E>: X{c.supers.first}<E>, {c}<E>"
336 write
"\toverride public long Id() \{ return {c.id}; \}"
337 write
"\tvirtual public long F{c.id}() \{ return {c.id}; \}"
338 write
"\tpublic long A{c.id} = {c.id};"
339 write
"\tpublic {cname}() \{ aid = {c.id}; \}"
343 write
"static void Main(string[] args) \{"
344 write
"\tRoot b = {ia.first};"
345 write
"\tRoot tmp = b;"
347 write
"\tb = b.SetNext({i});"
349 write
"\tb.SetNext(tmp);"
350 write
"\tRoot a = {ia.last};"
352 for i
in [1..poly
[ do
353 write
"\ta = a.SetNext({ia[ia.length - 1 - i]});"
355 write
"\ta.SetNext(tmp);"
356 write
"\tTest(b, b.GetNext(), 10, -100);"
357 write
"\tTest(a, a.GetNext(), {loops}, 0);"
360 write
"static void Test(Root a, Root b, long loops, long start) \{"
361 write
"\tlong x = start;"
362 write
"\tfor(long i = loops; i > 0; i--) \{"
363 write
"\t\tfor(long j = loops; j >0; j--) \{"
365 if not dry
then test
= testcsharp
(interfaces
)
366 write
"\t\t\tif({test}) \{"
367 write
"\t\t\t\tRoot tmp = a; a = b; b = tmp;"
368 if check
then write
"\t\t\t\tx++;"
369 write
"\t\t\t\} else \{ x += 1; a = a.GetNext(); b = b.GetNext();\};"
371 write
"\t\tx += 1; a = a.GetNext(); b = b.GetNext();"
373 write
"\tSystem.Console.WriteLine(x);"
379 fun initscala
(res
: Array[String], interfaces
: Bool) do return
380 fun testscala
(interfaces
: Bool): String do return "true"
381 fun writescala
(dir
: String, name
: String, interfaces
: Bool)
383 var ia
= new Array[String]
384 initscala
(ia
, interfaces
)
386 print
"Scala disabled"
392 file
= new FileWriter.open
("{dir}/{name}.scala")
394 write
"object {name} \{"
396 write
"class Root0 \{"
398 write
"class Root \{"
400 write
"\tdef id: Long = 0; var aid: Long = id; var next: Root = null; def getNext: Root = next; def setNext(next: Root): Root = \{ this.next = next; return next; \} \}"
403 write
"class Root extends Root0 \{\}"
408 write
"trait {c}[+E] "
410 write
"class {c}[+E] "
412 if c
.supers
.is_empty
then
413 write
"\textends Root"
414 else for s
in [c
.supers
.first
] do
415 write
"\textends {s}[E]"
419 if c
.supers
.is_empty
then
420 write
"class X{c}[E] extends {c}[E]"
422 write
"class X{c}[E] extends X{c.supers.first}[E] with {c}[E]"
426 write
"\toverride def id: Long = {c.id}"
427 write
"\tdef f{c.id}: Long = {c.id}"
429 write
"\tvar a{c.id}: Long = {c.id}"
434 write
"def main(args: Array[String]) = \{"
435 write
"\tvar b: Root = {ia.first};"
436 write
"\tvar tmp = b;"
438 write
"\tb = b.setNext({i});"
440 write
"\tb.setNext(tmp);"
441 write
"\tvar a: Root = {ia.last};"
443 for i
in [1..poly
[ do
444 write
"\ta = a.setNext({ia[ia.length - 1 - i]});"
446 write
"\ta.setNext(tmp);"
447 write
"\ttest(b, b.getNext, 10, -100);"
448 write
"\ttest(a, a.getNext, {loops}, 0);"
451 write
"def test(aa:Root, bb:Root, l: Long, start: Long) = \{"
454 write
"\tvar x = start"
455 write
"\tvar loops = l"
456 write
"\tvar i = loops"
457 write
"\twhile (i > 0) \{"
458 write
"\t\tvar j = loops"
459 write
"\t\twhile (j > 0) \{"
461 if not dry
then test
= testscala
(interfaces
)
462 write
"\t\t\tif ({test}) \{"
463 write
"\t\t\t\tval tmp = a; a = b; b = tmp;"
464 if check
then write
"\t\t\t\tx += 1;"
465 write
"\t\t\t\} else \{ x += 1; a = a.getNext; b = b.getNext;\}"
468 write
"\t\tx += 1; a = a.getNext; b = b.getNext;"
478 fun initcpp
(res
: Array[String]) do return
479 fun testcpp
: String do return "true"
480 fun writecpp
(dir
: String, name
: String)
482 var ia
= new Array[String]
491 file
= new FileWriter.open
("{dir}/{name}.cpp")
493 write
"#include <iostream>"
494 write
"#include <stdlib.h>"
501 write
"\t\{ public: virtual long id() \{ return 0;\} long aid; Root *next; virtual Root *setNext(Root *n) \{this->next = n; return n;\} \};"
504 write
"class Root: public virtual Root0 \{\};"
508 write
"template<class E>"
510 if c
.supers
.is_empty
then
511 write
"\t: public virtual Root"
512 else for s
in [c
.supers
.first
] do
513 write
"\t: public virtual {s}<E>"
516 write
"\tpublic: virtual long id() \{ return {c.id}; \}"
517 write
"\tvirtual long f{c.id}() \{ return {c.id}; \}"
518 write
"\tlong a{c.id};"
519 write
"\t{c}(): a{c.id}({c.id}) \{ this->aid = {c.id}; \}"
523 write
"void test(Root *a, Root *b, long loops, long start) \{"
524 write
"\tlong x = start;"
525 write
"\tfor(long i = loops; i > 0; i--) \{"
526 write
"\t\tfor(int j = loops; j > 0; j--) \{"
528 if not dry
then test
= testcpp
529 write
"\t\t\tif({test}) \{"
530 write
"\t\t\t\tRoot *tmp = a; a = b; b = tmp;"
531 if check
then write
"\t\t\t\tx += 1;"
532 write
"\t\t\t\} else \{ x++; a = a->next; b = b->next;\}"
534 write
"\t\tx++; a = a->next; b = b->next;"
536 write
"\tstd::cout << x << std::endl;"
539 write
"int main(int argc, char **argv) \{"
540 write
"\tRoot *b = {ia.first};"
541 write
"\tRoot *tmp = b;"
543 write
"\tb = b->setNext({i});"
545 write
"\tb->setNext(tmp);"
546 write
"\tRoot *a = {ia.last};"
548 for i
in [1..poly
[ do
549 write
"\ta = a->setNext({ia[ia.length - 1 - i]});"
551 write
"\ta->setNext(tmp);"
552 write
"\ttest(b, b->next, 10, -100);"
553 write
"\ttest(a, a->next, {loops}, 0);"
559 fun inite
(res
: Array[String], se
: Bool) do return
560 fun teste
(se
: Bool): String do return "true"
561 fun locale
(se
: Bool) do end
562 fun writee
(dir
: String, name
: String, se
: Bool)
564 var ia
= new Array[String]
567 print
"Eiffel disabled"
572 dir
= "{dir}/se/{name}"
574 dir
= "{dir}/es/{name}"
581 file
= new FileWriter.open
("{dir}/root0.e")
584 file
= new FileWriter.open
("{dir}/root.e")
588 if se
then istk
= " is"
589 write
"class {root0}"
590 write
"feature id: INTEGER_64 {istk} do Result := 0 end"
591 write
"aid: INTEGER_64"
592 write
"xnext: detachable ROOT"
593 write
"next: ROOT do check attached xnext as n then Result := n end end"
594 write
"set_next(n: ROOT): ROOT do xnext := n Result := n end"
595 write
"make do aid := id end"
600 file
= new FileWriter.open
("{dir}/root.e")
601 write
"class ROOT inherit ROOT0 end "
606 file
= new FileWriter.open
("{dir}/{c}.e")
607 write
"class {c}[E] "
608 if c
.supers
.is_empty
then
609 write
"\tinherit ROOT"
610 else for s
in [c
.supers
.first
] do
611 write
"\tinherit {s}[E]"
613 write
"\t\tredefine id, make end"
616 write
"\tid: INTEGER_64 {istk} do Result := {c.id} end"
617 write
"\tf{c.id}: INTEGER_64 {istk} do Result := {c.id} end"
618 write
"\ta{c.id}: INTEGER_64 {istk} attribute Result := {c.id} end"
619 write
"make do aid := {c.id} end"
624 file
= new FileWriter.open
("{dir}/app{name}.e")
625 write
"class APP{name.to_upper}"
627 write
"insert ARGUMENTS"
635 write
"\tmake(args: ARRAY[STRING]){istk}"
638 write
"\t\t\ta: ROOT"
639 write
"\t\t\tb: ROOT"
640 write
"\t\t\ttmp: ROOT"
642 write
"\t\t\tb := {ia.first} .make"
643 write
"\t\t\ttmp := b"
645 write
"\t\t\tb := b.set_next({i} .make)"
647 write
"\t\t\ttmp := b.set_next(tmp)"
649 write
"\t\t\ta := {ia.last} .make"
650 write
"\t\t\ttmp := a"
651 for i
in [1..poly
[ do
652 write
"\t\t\ta := a.set_next({ia[ia.length - 1 - i]} .make)"
654 write
"\t\t\ttmp := a.set_next(tmp);"
655 write
"\t\t\ttest(b, b.next, 10, -100)"
656 write
"\t\t\ttest(a, a.next, {loops}, 0)"
659 write
"\ttest(aa: ROOT; bb: ROOT; l: INTEGER_64; start: INTEGER_64){istk}"
661 write
"\t\t\ta: ROOT"
662 write
"\t\t\tb: ROOT"
663 write
"\t\t\ttmp: ROOT"
664 write
"\t\t\ti: INTEGER_64"
665 write
"\t\t\tj: INTEGER_64"
666 write
"\t\t\tx: INTEGER_64"
668 write
"\t\t\tloops: INTEGER_64"
670 write
"\t\t\ta := aa"
671 write
"\t\t\tb := bb"
672 write
"\t\t\tx := start"
673 write
"\t\t\tloops := l"
674 write
"\t\t\tfrom i := loops until i<=0 loop"
675 write
"\t\t\t\tfrom j := loops until j<=0 loop"
677 if not dry
then test
= teste
(se
)
678 write
"\t\t\t\t\tif {test} then"
679 write
"\t\t\t\t\t\ttmp := a; a := b; b := tmp"
680 if check
then write
"\t\t\t\t\tx := x + 1"
681 write
"\t\t\t\t\telse x := x + 1; a := a.next; b := b.next end"
682 write
"\t\t\t\t\tj := j - 1"
684 write
"\t\t\t\tx := x + 1; a := a.next; b := b.next"
685 write
"\t\t\t\ti := i - 1"
687 write
"\t\t\tprint(x.out)"
688 write
"\t\t\tprint(\"%N\
")"
694 fun initpython
(res
: Array[String]) do return
695 fun testpython
: String do return "true"
696 fun writepython
(dir
: String, name
: String)
698 var ia
= new Array[String]
701 print
"Python disabled"
707 file
= new FileWriter.open
("{dir}/{name}.py")
710 write
"class Root0(object):"
712 write
"class Root(object):"
714 write
"\tdef id(self): return 0"
715 write
"\tdef set_next(self, n):\n\t\tself.next = n\n\t\treturn n"
716 write
"\tdef __init__(self): self.aid = self.id()"
719 write
"class Root(Root0): pass"
723 if c
.supers
.is_empty
then
724 write
"class {c}(Root):"
726 write
"class {c}({c.supers.join(",")}):"
728 write
"\tdef id(self): return {c.id}"
729 write
"\tdef f{c.id}(self): return {c.id}"
730 write
"\tdef __init__(self):"
731 write
"\t\tsuper({c}, self).__init__()"
732 write
"\t\ta{c.id} = {c.id}"
735 write
"def test(a, b, loops, start):"
738 write
"\twhile i > 0:"
739 write
"\t\tj = loops"
740 write
"\t\twhile j > 0:"
742 if not dry
then test
= testpython
743 write
"\t\t\tif {test}:"
744 write
"\t\t\t\ttmp = a; a = b; b = tmp"
745 if check
then write
"\t\t\t\tx += 1"
747 write
"\t\t\t\tx = x + 1; a = a.next; b = b.next"
749 write
"\t\tx = x + 1; a = a.next; b = b.next"
753 write
"b = {ia.first}"
756 write
"b = b.set_next({i})"
759 write
"a = {ia.last}"
761 for i
in [1..poly
[ do
762 write
"a = a.set_next({ia[ia.length - 1 - i]})"
765 write
"test(b, b.next, 10, -100)"
766 write
"test(a, a.next, {loops}, 0)"
776 var outdir
= args
.first
778 var use_interfaces
= self.use_interfaces
779 if args
.length
> 2 then g
.dept
= args
[2].to_i
780 if args
.length
> 3 then loops
= args
[3].to_i
781 if args
.length
> 4 then use_interfaces
= false
785 g
.writenit
(outdir
, name
)
786 g
.writejava
(outdir
, name
, use_interfaces
)
787 g
.writecsharp
(outdir
, name
, use_interfaces
)
788 g
.writescala
(outdir
, name
, use_interfaces
)
789 g
.writecpp
(outdir
, name
)
790 g
.writee
(outdir
, "{name}_se", true)
791 g
.writee
(outdir
, name
, false)
792 g
.writepython
(outdir
, name
)
796 var g
= new Generator