bench/lang: add bench_base
[nit.git] / benchmarks / languages / bench_typetest_depth.nit
index 5e60571..d5d2f2a 100644 (file)
 #!/usr/bin/env nit
 
-# Microbenchmak generation for multiple language
-# Just a quick an dirty Nit script file :)
+import bench_base
 
-# This benchmark focuses on effects of the hierarchy dept
-# on the typetest performances
+class TypeTestDepthGenerator
+       super Generator
 
-# class Root
-# class Klass[E] super Root
-# class C1...CX super Root
-# Klass[CX] isa Klass[C1]
-
-class Klass
-       var id: Int
-       var supers = new Array[Klass]
-       var all_supers = new HashSet[Klass]
-       redef fun to_s
-       do
-               return "C{id}"
-       end
-end
-
-class Generator
-
-       var classes = new Array[Klass]
-
-       var dept = 5
-       var loops = 50000
-       var middle = 0
-       var dry =  false
-       var check = false
-
-       fun genhier
+       redef fun initnit(res)
        do
-               var s: nullable Klass = null
-               for d in [1..dept] do
-                       var c = new Klass(d)
-
-                       classes.add(c)
-                       c.all_supers.add(c)
-                       if s != null then
-                               c.supers.add(s)
-                               c.all_supers.add_all(s.all_supers)
-                       end
-                       s = c
+               for c in classes do
+                       res.add "new {c}[Root]"
                end
-               middle = (dept + 1) / 2
-       end
 
-       var file: nullable OFStream = null
-       fun write(str: String)
-       do
-               file.write(str)
-               file.write("\n")
        end
 
-       fun writenit(dir: String, name: String)
+       redef fun testnit
        do
-               dir = "{dir}/nit"
-               dir.mkdir
-               file = new OFStream.open("{dir}/{name}.nit")
-
-               write "class Root\n\tfun id: Int do return 0\nend"
-               for c in classes do
-                       write "class {c}[E]"
-                       if c.supers.is_empty then
-                               write "\tsuper Root"
-                       else for s in c.supers do
-                               write "\tsuper {s}[E]"
-                       end
-                       write "\tredef fun id do return {c.id}"
-                       write "end"
-               end
-
-               write "fun test(a,b: Root, loops, start: Int)"
-               write "do"
-               write "var x = start"
-               write "var i = 0"
-               write "while i < loops do"
-               write "\tvar j = 0"
-               write "\twhile j < loops do"
-               var test
-               if dry then test = "" else test = "a isa {classes[middle]}[Root] and "
-               write "\t\tif {test}x >= 0 then"
-               if check then write "\t\tx += 1"
-               write "\telse"
-               write "\t\t\tx -= 1"
-               write "\t\t\ta = b"
-               write "\t\tend"
-               write "\t\tj += 1"
-               write "\tend"
-               write "\ti += 1"
-               write "end"
-               write "print x"
-               write "end"
-
-               write "var a: Root = new {classes.first}[Root]"
-               write "var b: Root = a"
-               for c in classes do
-                       write "\t\t\tif a.id > 0 then a = new {c}[Root]"
-               end
-               write "test(b, b, 10, -100)"
-               write "test(a, a, {loops}, 0)"
-
-               file.close
+               return "a isa {classes[middle]}[Root]"
        end
 
-       fun writejava(dir: String, name: String, interfaces: Bool)
+       redef fun initjava(res, interfaces)
        do
-               dir = "{dir}/java"
-               dir.mkdir
-               file = new OFStream.open("{dir}/{name}.java")
-
-               var cl = ""
-               if interfaces then cl = "X"
-               write "class {name} \{"
-               if interfaces then
-                       write "static interface Root\n\t\{ int id(); \}"
-               else
-                       write "static class Root\n\t\{ int id() \{ return 0;\} \}"
-               end
-               for c in classes do
-                       if interfaces then
-                               write "static interface {c}<E> "
-                       else
-                               write "static class {c}<E> "
-                       end
-                       if c.supers.is_empty then
-                               write "\textends Root"
-                       else for s in [c.supers.first] do
-                               write "\textends {s}<E>"
-                       end
-                       if interfaces then
-                               write "\{\}"
-                               write "static class X{c}<E> implements {c}<E>"
-                       end
-                       write "\{"
-                       write "\tpublic int id() \{ return {c.id}; \}"
-                       write "\}"
-               end
 
-               write "static public void main(String args[]) \{"
                var tagc = ""
                if interfaces then tagc = "X"
-               write "\tRoot a = new {tagc}{classes.first}<Root>();"
-               write "\tRoot b = a;"
                for c in classes do
-                       write "\t\t\tif (a.id() > 0) a = new {tagc}{c}<Root>();"
+                       res.add "new {tagc}{c}<Root>()"
                end
-               write "\ttest(b, b, 10, -100);"
-               write "\ttest(a, a, {loops}, 0);"
-               write "\}"
-
-               write "static public void test(Root a, Root b, int loops, int start) \{"
-               write "\tint x = start;"
-               write "\tfor(int i = 0; i < loops; i++) \{"
-               write "\t\tfor(int j = 0; j < loops; j++) \{"
-               var test
-               if dry then test = "" else test = "a instanceof {classes[middle]} && "
-               write "\t\t\tif({test}x>=0) \{"
-               if check then write "\t\t\t\tx -= 2"
-               write "\t\t\t\} else \{ x--; a = b;\}"
-               write "\t\t}"
-               write "\t\}"
-               write "\tSystem.out.println(x);"
-               write "\}"
-               write "\}"
-               file.close
        end
 
-       fun writecsharp(dir: String, name: String, interfaces: Bool)
+       redef fun testjava(interfaces)
        do
-               dir = "{dir}/cs"
-               dir.mkdir
-               file = new OFStream.open("{dir}/{name}.cs")
-
-               var cl = ""
-               if interfaces then cl = "X"
-               write "class {name} \{"
-               if interfaces then
-                       write "interface Root\n\t\{ int Id(); \}"
-               else
-                       write "class Root\n\t\{ public int Id() \{ return 0;\} \}"
-               end
-               for c in classes do
-                       if interfaces then
-                               write "interface {c}<E> "
-                       else
-                               write "class {c}<E> "
-                       end
-                       if c.supers.is_empty then
-                               write "\t: Root"
-                       else for s in [c.supers.first] do
-                               write "\t: {s}<E>"
-                       end
-                       if interfaces then
-                               write "\{\}"
-                               write "class X{c}<E> : {c}<E>"
-                       end
-                       write "\{"
-                       write "\tpublic int Id() \{ return {c.id}; \}"
-                       write "\}"
-               end
+               return "a instanceof {classes[middle]}"
+       end
 
-               write "static void Main(string[] args) \{"
+       redef fun initcsharp(res, interfaces)
+       do
                var tagc = ""
                if interfaces then tagc = "X"
-               write "\tRoot a = new {tagc}{classes.first}<Root>();"
-               write "\tRoot b = a;"
                for c in classes do
-                       write "\t\t\tif (a.Id() > 0) a = new {tagc}{c}<Root>();"
+                       res.add "new {tagc}{c}<Root>()"
                end
-               write "\tTest(b, b, 10, -100);"
-               write "\tTest(a, a, {loops}, 0);"
-               write "\}"
-
-               write "static void Test(Root a, Root b, int loops, int start) \{"
-               write "\tint x = start;"
-               write "\tfor(int i = 0; i < loops; i++) \{"
-               write "\t\tfor(int j = 0; j < loops; j++) \{"
-               var test
-               if dry then test = "" else test = "a is {classes[middle]}<Root> && "
-               write "\t\t\tif({test}x>=0) \{"
-               if check then write "\t\t\t\tx++;"
-               write "\} else \{ x--; a = b; \};"
-               write "\t\t}"
-               write "\t\}"
-               write "\tSystem.Console.WriteLine(x);"
-               write "\}"
-               write "\}"
-               file.close
        end
 
-       fun writescala(dir: String, name: String, interfaces: Bool)
+       redef fun testcsharp(interfaces)
        do
-               dir = "{dir}/scala"
-               dir.mkdir
-               file = new OFStream.open("{dir}/{name}.scala")
-
-               var cl = ""
-               write "object {name} \{"
-               write "class Root\n\t\{ def id: Int = 0 \}"
-               for c in classes do
-                       if interfaces then
-                               write "trait {c}[E] "
-                       else
-                               write "class {c}[E] "
-                       end
-                       if c.supers.is_empty then
-                               write "\textends Root"
-                       else for s in [c.supers.first] do
-                               write "\textends {s}[E]"
-                       end
-                       if interfaces then
-                               write "\{\}"
-                               write "class X{c}[E] extends {c}[E]"
-                       end
-                       write "\{"
-                       write "\toverride def id: Int = {c.id}"
-                       write "\}"
-               end
+               return "a is {classes[middle]}<Root>"
+       end
 
-               write "def main(args: Array[String]) = \{"
+       redef fun initscala(res, interfaces)
+       do
                var tagc = ""
                if interfaces then tagc = "X"
-               write "\tvar a:Root = new {tagc}{classes.first}[Root]()"
-               write "\tvar b:Root = a"
                for c in classes do
-                       write "\t\t\tif (a.id > 0) a = new {tagc}{c}[Root]();"
+                       res.add "new {tagc}{c}[Root]()"
                end
-               write "\ttest(b, b, 10, -100)"
-               write "\ttest(a, a, {loops}, 0)"
-               write "\}"
-
-               write "def test(aa:Root, b:Root, l: Int, start: Int) = \{"
-               write "\tvar a = aa"
-               write "\tvar x = start"
-               write "\tvar loops = l"
-               write "\tvar i = 0"
-               write "\twhile (i < loops) \{"
-               write "\t\tvar j = 0"
-               write "\t\twhile (j < loops) \{"
-               var test
-               if dry then test = "" else test = "a.isInstanceOf[{classes[middle]}[Root]] && "
-               write "\t\tif ({test}x>=0) \{"
-               if check then write "\t\t\tx += 1"
-               write "\} else \{ x = x - 1; a = b; \}"
-               write "\t\tj += 1"
-               write "\t\t\}"
-               write "\ti += 1"
-               write "\t\}"
-               write "\t\t\tprintln(x)"
-               write "\}"
-               write "\}"
-
-               file.close
        end
 
-       fun writecpp(dir: String, name: String)
+       redef fun testscala(interfaces)
        do
-               dir = "{dir}/cpp"
-               dir.mkdir
-               file = new OFStream.open("{dir}/{name}.cpp")
-
-               write "#include <iostream>"
-               write "#include <stdlib.h>"
-               write "class Root\n\t\{ public: virtual int id() \{ return 0;\} \};"
-               for c in classes do
-                       write "template<class E>"
-                       write "class {c} "
-                       if c.supers.is_empty then
-                               write "\t: public virtual Root"
-                       else for s in [c.supers.first] do
-                               write "\t: public virtual {s}<E>"
-                       end
-                       write "\{"
-                       write "\tpublic: virtual int id() \{ return {c.id}; \}"
-                       write "\};"
-               end
-
-               write "void test(Root *a, Root *b, int loops, int start) \{"
-               write "\tint x = start;"
-               write "\tfor(int i = 0; i < loops; i++) \{"
-               write "\t\tfor(int j = 0; j < loops; j++) \{"
-               var test
-               if dry then test = "" else
-                       write "\t\t\t{classes[middle]}<Root> *to = dynamic_cast<{classes[middle]}<Root>*>(a);"
-                       test = "to != 0 &&"
-               end
-               write "\t\tif({test}x>=0) \{"
-               if check then write "\t\t\tx += 1"
-               write "\} else \{ x--; a = b;\}"
-               write "\t\t}"
-               write "\t\}"
-               write "\tstd::cout << x << std::endl;"
-               write "\}"
+               return "a.isInstanceOf[{classes[middle]}[Root]]"
+       end
 
-               write "int main(int argc, char **argv) \{"
-               write "\tRoot *a = new {classes.first}<Root>();"
-               write "\tRoot *b = a;"
+       redef fun initcpp(res)
+       do
                for c in classes do
-                       write "\t\t\tif (a->id() > 0) a = new {c}<Root>();"
+                       res.add "new {c}<Root>()"
                end
-               write "\ttest(b, b, 10, -100);"
-               write "\ttest(a, a, {loops}, 0);"
-               write "\}"
-
-               file.close
        end
 
-       fun writee(dir: String, name: String, se: Bool)
+       redef fun testcpp
        do
-               if se then
-                       dir = "{dir}/se/{name}"
-               else
-                       dir = "{dir}/es/{name}"
-               end
-               dir.mkdir
-               file = new OFStream.open("{dir}/root.e")
-
-               var istk = ""
-               if se then istk = " is"
-               write "class ROOT"
-               write "feature id: INTEGER {istk} do Result := 0 end"
-               write "end"
-               file.close
+               write "\t\t\t{classes[middle]}<Root> *to = dynamic_cast<{classes[middle]}<Root>*>(a);"
+               return "to != 0"
+       end
 
+       redef fun inite(res, se)
+       do
                for c in classes do
-                       file = new OFStream.open("{dir}/{c}.e")
-                       write "class {c}[E] "
-                       if c.supers.is_empty then
-                               write "\tinherit ROOT"
-                       else for s in [c.supers.first] do
-                               write "\tinherit {s}[E]"
-                       end
-                       write "\t\tredefine id end"
-                       write "feature"
-                       write "\tid: INTEGER {istk} do Result := {c.id} end"
-                       write "end"
-                       file.close
-               end
-
-               file = new OFStream.open("{dir}/app{name}.e")
-               write "class APP{name.to_upper}"
-               if se then
-                       write "insert ARGUMENTS"
+                       res.add "create \{{c}[ROOT]\} a"
                end
-               write "create make"
-               write "feature"
+       end
 
-               if se then
-                       write "\tmake{istk}"
-               else
-                       write "\tmake(args: ARRAY[STRING]){istk}"
-               end
-               write "\t\tlocal"
-               write "\t\t\ta: ROOT"
-               write "\t\t\tb: ROOT"
-               write "\t\tdo"
-               write "\t\t\tcreate \{{classes.first}[ROOT]\} a"
-               write "\t\t\tb := a"
-               for c in classes do
-                       write "\t\t\tif a.id > 0 then create \{{c}[ROOT]\} a end"
-               end
-               write "\t\t\ttest(b, b, 10, -100)"
-               write "\t\t\ttest(a, a, {loops}, 0)"
-               write "\t\tend"
+       redef fun teste(se)
+       do
+               write "\t\t\t\t\tto ?= a"
+               return "to /= Void"
+       end
 
-               write "\ttest(a: ROOT; b: ROOT; l: INTEGER; start: INTEGER){istk}"
-               write "\t\tlocal"
-               write "\t\t\to: ROOT"
+       redef fun locale(se)
+       do
                write "\t\t\tto: {classes[middle]}[ROOT]"
-               write "\t\t\ti: INTEGER"
-               write "\t\t\tj: INTEGER"
-               write "\t\t\tx: INTEGER"
-               write "\t\t\tloops: INTEGER"
-               write "\t\tdo"
-               write "\t\t\to := a"
-               write "\t\t\tx := start"
-               write "\t\t\tloops := l"
-               write "\t\t\tfrom i := 0 until i>=loops loop"
-               write "\t\t\t\tfrom j := 0 until j>=loops loop"
-               var test
-               if dry then
-                       test = ""
-               else
-                       write "\t\t\t\t\tto ?= o"
-                       test = "to /= Void and then "
-               end
-               write "\t\t\t\t\tif {test}x >= 0 then" 
-               if check then write "\t\t\t\t\tx := x + 1"
-               write "\t\t\t\t\telse x := x - 1; o := b end"
-               write "\t\t\t\t\tj := j + 1"
-               write "\t\t\t\tend"
-               write "\t\t\t\ti := i + 1"
-               write "\t\t\tend"
-               write "\t\t\tprint(x.out)"
-               write "\t\tend"
-               write "end"
-               file.close
        end
-
-       var count = false
 end
 
-var g = new Generator
-var outdir = args.first
-var name = args[1]
-var use_interfaces = true
-if args.length > 2 then g.dept = args[2].to_i
-if args.length > 3 then use_interfaces = false
-
-g.genhier
-
-g.writenit(outdir, name)
-g.writejava(outdir, name, use_interfaces)
-g.writecsharp(outdir, name, use_interfaces)
-g.writescala(outdir, name, use_interfaces)
-g.writecpp(outdir, name)
-g.writee(outdir, "{name}_se", true)
-g.writee(outdir, name, false)
+var g = new TypeTestDepthGenerator
+g.genall