benches: moved bench in its own directory at project root
authorAlexandre Terrasa <alexandre@moz-code.org>
Mon, 15 Jul 2013 18:17:45 +0000 (14:17 -0400)
committerJean Privat <jean@pryen.org>
Mon, 15 Jul 2013 18:18:08 +0000 (14:18 -0400)
* bench_plot provides plot facilities
* bench_engines provides nit* engines benchmarks
* bench_languages provides language comparison on generic subtyping test performances

Signed-off-by: Alexandre Terrasa <alexandre@moz-code.org>

benchmarks/bench_engines.sh [moved from src/run_bench.sh with 60% similarity]
benchmarks/bench_languages.sh [new file with mode: 0755]
benchmarks/bench_plot.sh [new file with mode: 0755]
benchmarks/languages/bench_typetest_depth.nit [new file with mode: 0644]
src/benchs/gen.nit [deleted file]

similarity index 60%
rename from src/run_bench.sh
rename to benchmarks/bench_engines.sh
index 1388d6c..3a42a04 100755 (executable)
@@ -17,6 +17,8 @@
 
 # TODO: cleanup and libify the helper-parts
 
+source ./bench_plot.sh
+
 ## CONFIGURATION OPTIONS ##
 
 # Default number of times a command must be run with bench_command
@@ -75,87 +77,6 @@ function run_command()
        "$@" || die "$@: failed"
 }
 
-# perl function to compute min/max/avg.
-# used by bench_command
-#
-# $1: file
-# return: first min max avg label
-function compute_stats()
-{
-       file="$1"
-       # Compute statistics
-       perl - "$file" <<'END'
-       @lines = ();
-       $first = undef;
-       chomp($label = <>);
-       while(<>) {
-               chomp;
-               if (/^\d/) {
-                       if (defined $first) {
-                               push @lines, $_;
-                       } else {
-                               $first = $_;
-                       }
-               }
-       }
-       $len = scalar @lines;
-       if ($len) {
-               @lines = sort {$a <=> $b} @lines;
-               $min = $lines[0];
-               $max = $lines[$#lines];
-               $avg = 0;
-               for $i (@lines) { $avg += $i; }
-               $avg = $avg / $len;
-               print "${first} ${min} ${max} ${avg} \"${label}\"\n";
-       } else {
-               print "${first} ${first} ${first} ${first} \"${label}\"\n";
-       }
-END
-}
-
-# Create a new $res to be used in the next plot
-#
-# $1 = resfile
-# $2 = title
-# $3 = description
-function prepare_res()
-{
-       echo
-       echo "# [$2] $3 #"
-       res=$1
-       if [ "$plots" = "" ]; then
-               plots="plot '$1' using 4:2:3:xticlabels(5) ti '$2';"
-       else
-               plots="$plots replot '$1' using 4:2:3 ti '$2';"
-       fi
-       if [ "$dry_run" = "true" ]; then return; fi
-       echo "# [$2] $3 ; count=$count" > "$res"
-       echo "# first min max avg title" >> "$res"
-}
-
-# Plot the last $res as an histogram
-# $1: plot file (eg toto.gnu)
-function plot()
-{
-       cat >"$1" <<END
-set auto x;
-set yrange [0:];
-set style data histogram;
-set style histogram cluster gap 2;
-set style histogram errorbars linewidth 1;
-set style fill solid 0.3 border -1;
-set bars front;
-set boxwidth 0.9;
-set xtic nomirror rotate by -45 scale 0 font ',8';
-set title "$1 ; avg. on $count-1 runs"
-set ylabel "time (s)"
-$plots
-END
-       echo "# gnuplot -p $1"
-       gnuplot -p "$1"
-       plots=
-}
-
 # Check if the test should be skiped according to its name
 # $1: name of the test
 # $2: description of the test
@@ -179,14 +100,6 @@ function skip_test()
        return 1
 }
 
-## GLOBAL VARIABLES ##
-
-# The current $res (set by prepare_res, used by bench_command)
-res=
-
-# The current stuff to plot (set by prepare_res, used by plot)
-plots=
-
 # HELPER FOR NIT #
 
 # Run standards benchs on a compiler command
@@ -197,20 +110,20 @@ function run_compiler()
        local title=$1
        shift
        if test -n "$fast"; then
-               run_command "$@" nitg.nit -o "nitg.$title.bin"
-               bench_command "nitg" "nitg test_parser.nit" "./nitg.$title.bin" -v --no-cc test_parser.nit
-               run_command "$@" nit.nit -o "nit.$title.bin"
-               bench_command "nit" "nit test_parser.nit location.nit" "./nit.$title.bin" -v test_parser.nit -- -n location.nit
+               run_command "$@" ../src/nitg.nit -o "nitg.$title.bin"
+               bench_command "nitg" "nitg ../src/test_parser.nit" "./nitg.$title.bin" -v --no-cc ../src/test_parser.nit
+               run_command "$@" ../src/nit.nit -o "nit.$title.bin"
+               bench_command "nit" "nit ../src/test_parser.nit ../src/location.nit" "./nit.$title.bin" -v ../src/test_parser.nit -- -n ../src/location.nit
                run_command "$@" ../examples/shoot/shoot_logic.nit -o "shoot.$title.bin"
                bench_command "shoot" "shoot_logic" "./shoot.$title.bin"
                run_command "$@" ../tests/bench_bintree_gen.nit -o "bintrees.$title.bin"
                bench_command "bintrees" "bench_bintree_gen 16" "./bintrees.$title.bin" 16
        else
-               run_command "$@" nitg.nit -o "nitg.$title.bin"
-               bench_command "nitg" "nitg --no-cc nitstats.nit" "./nitg.$title.bin" -v --no-cc nitstats.nit
-               bench_command "nitg-s" "nitg --separate nitg.nit" "./nitg.$title.bin" -v --no-cc --separate nitg.nit
-               run_command "$@" nit.nit -o "nit.$title.bin"
-               bench_command "nit" "nit test_parser.nit rapid_type_analysis.nit" "./nit.$title.bin" -v test_parser.nit -- -n rapid_type_analysis.nit
+               run_command "$@" ../src/nitg.nit -o "nitg.$title.bin"
+               bench_command "nitg" "nitg --no-cc ../src/nitstats.nit" "./nitg.$title.bin" -v --no-cc ../src/nitstats.nit
+               bench_command "nitg-s" "nitg --separate ../src/nitg.nit" "./nitg.$title.bin" -v --no-cc --separate ../src/nitg.nit
+               run_command "$@" ../src/nit.nit -o "nit.$title.bin"
+               bench_command "nit" "nit ../src/test_parser.nit ../src/rapid_type_analysis.nit" "./nit.$title.bin" -v ../src/test_parser.nit -- -n ../src/rapid_type_analysis.nit
                run_command "$@" ../examples/shoot/shoot_logic.nit -o "shoot.$title.bin"
                bench_command "shoot" "shoot_logic 30" "./shoot.$title.bin" 30
                run_command "$@" ../tests/bench_bintree_gen.nit -o "bintrees.$title.bin"
@@ -252,8 +165,8 @@ fi
 
 ## COMPILE ENGINES
 
-test -f ./nitc_3 || ./ncall.sh -O
-test -f ./nitg || ./nitc_3 nitg.nit -O -v
+test -f ../src/nitc_3 || ../src/ncall.sh -O
+test -f ./nitg || ../src/nitc_3 ../src/nitg.nit -O -v
 
 ## EFFECTIVE BENCHS ##
 
@@ -263,11 +176,11 @@ function bench_nitg_bootstrap()
        skip_test "$name" && return
        prepare_res "$name.dat" "" "Steps of the bootstrap of nitg by nitc"
        rm nit?_nit*
-       cp ./nitc_3 ./nitc_nitc.bin
-       bench_command "c/c c" "nitc_nitc nitc.nit -> nitc_nitc (stability)" ./nitc_nitc.bin -O nitc.nit -o nitc_nitc.bin
-       bench_command "c/c g" "nitc_nitc nitg.nit -> nitg_nitc" ./nitc_nitc.bin -O nitg.nit -o nitg_nitc.bin
-       bench_command "g/c g" "nitg_nitc nitg.nit -> nitg_nitg" ./nitg_nitc.bin nitg.nit -o nitg_nitg.bin
-       bench_command "g/g g" "nitg_nitg nitg.nit -> nitg_nitg (stability)" ./nitg_nitg.bin nitg.nit -o nitg_nitg.bin
+       cp ../src/nitc_3 ./nitc_nitc.bin
+       bench_command "c/c c" "nitc_nitc ../src/nitc.nit -> nitc_nitc (stability)" ./nitc_nitc.bin -O ../src/nitc.nit -o nitc_nitc.bin
+       bench_command "c/c g" "nitc_nitc ../src/nitg.nit -> nitg_nitc" ./nitc_nitc.bin -O ../src/nitg.nit -o nitg_nitc.bin
+       bench_command "g/c g" "nitg_nitc ../src/nitg.nit -> nitg_nitg" ./nitg_nitc.bin ../src/nitg.nit -o nitg_nitg.bin
+       bench_command "g/g g" "nitg_nitg ../src/nitg.nit -> nitg_nitg (stability)" ./nitg_nitg.bin ../src/nitg.nit -o nitg_nitg.bin
 
        plot "$name.gnu"
 }
@@ -278,28 +191,28 @@ function bench_steps()
        name="$FUNCNAME"
        skip_test "$name" && return
        prepare_res "$name-nitc.dat" "nitc" "Various steps of nitc"
-       bench_command "parse" "" ./nitc_3 --only-parse nitg.nit
-       bench_command "metamodel" "" ./nitc_3 --only-metamodel nitg.nit
-       bench_command "generate c" "" ./nitc_3 --no-cc nitg.nit
-       bench_command "full" "" ./nitc_3 -O nitg.nit -o "nitg_nitg.bin"
+       bench_command "parse" "" ../src/nitc_3 --only-parse ../src/nitg.nit
+       bench_command "metamodel" "" ../src/nitc_3 --only-metamodel ../src/nitg.nit
+       bench_command "generate c" "" ../src/nitc_3 --no-cc ../src/nitg.nit
+       bench_command "full" "" ../src/nitc_3 -O ../src/nitg.nit -o "nitg_nitg.bin"
 
        prepare_res "$name-nitc-g.dat" "nitc-g" "Various steps of nitc --global"
-       bench_command "parse" "" ./nitc_3 --global --only-parse nitg.nit
-       bench_command "metamodel" "" ./nitc_3 --global --only-metamodel nitg.nit
-       bench_command "generate c" "" ./nitc_3 --global --no-cc nitg.nit
-       bench_command "full" "" ./nitc_3 -O --global nitg.nit -o "nitg_nitc-g.bin"
+       bench_command "parse" "" ../src/nitc_3 --global --only-parse ../src/nitg.nit
+       bench_command "metamodel" "" ../src/nitc_3 --global --only-metamodel ../src/nitg.nit
+       bench_command "generate c" "" ../src/nitc_3 --global --no-cc ../src/nitg.nit
+       bench_command "full" "" ../src/nitc_3 -O --global ../src/nitg.nit -o "nitg_nitc-g.bin"
 
        prepare_res "$name-nitg.dat" "nitg" "Various steps of nitg"
-       bench_command "parse" "" ./nitg --only-parse nitg.nit
-       bench_command "metamodel" "" ./nitg --only-metamodel nitg.nit
-       bench_command "generate c" "" ./nitg --no-cc nitg.nit
-       bench_command "full" "" ./nitg nitg.nit -o "nitg_nitg.bin"
+       bench_command "parse" "" ./nitg --only-parse ../src/nitg.nit
+       bench_command "metamodel" "" ./nitg --only-metamodel ../src/nitg.nit
+       bench_command "generate c" "" ./nitg --no-cc ../src/nitg.nit
+       bench_command "full" "" ./nitg ../src/nitg.nit -o "nitg_nitg.bin"
 
        prepare_res "$name-nitg-e.dat" "nitg-e" "Various steps of nitg --erasure"
-       bench_command "parse" "" ./nitg --erasure --only-parse nitg.nit
-       bench_command "metamodel" "" ./nitg --erasure --only-metamodel nitg.nit
-       bench_command "generate c" "" ./nitg --erasure --no-cc nitg.nit
-       bench_command "full" "" ./nitg --erasure nitg.nit -o "nitg_nitg-e.bin"
+       bench_command "parse" "" ./nitg --erasure --only-parse ../src/nitg.nit
+       bench_command "metamodel" "" ./nitg --erasure --only-metamodel ../src/nitg.nit
+       bench_command "generate c" "" ./nitg --erasure --no-cc ../src/nitg.nit
+       bench_command "full" "" ./nitg --erasure ../src/nitg.nit -o "nitg_nitg-e.bin"
 
        plot "$name.gnu"
 }
@@ -389,7 +302,7 @@ function bench_nitc_gc()
        for gc in nitgc boehm malloc large; do
                prepare_res "$name-$gc.dat" "$gc" "nitc with gc=$gc"
                export NIT_GC_OPTION="$gc"
-               run_compiler "nitc" ./nitc_3 -O
+               run_compiler "nitc" ../src/nitc_3 -O
        done
 
        plot "$name.gnu"
@@ -401,9 +314,9 @@ function bench_nitc_boost()
        name="$FUNCNAME"
        skip_test "$name" && return
        prepare_res "$name-slow.dat" "no -O" "nitc without -O"
-       run_compiler "nitc_slow" ./nitc_3
+       run_compiler "nitc_slow" ../src/nitc_3
        prepare_res "$name-fast.dat" "-O" "nitc with -O"
-       run_compiler "nitc" ./nitc_3 -O
+       run_compiler "nitc" ../src/nitc_3 -O
 
        plot "$name.gnu"
 }
@@ -414,9 +327,9 @@ function bench_engines()
        name="$FUNCNAME"
        skip_test "$name" && return
        prepare_res "$name-nitc.dat" "nitc" "nitc"
-       run_compiler "nitc" ./nitc_3 -O
+       run_compiler "nitc" ../src/nitc_3 -O
        prepare_res "$name-nitc-g.dat" "nitc-g" "nitc with --global"
-       run_compiler "nitc-g" ./nitc_3 -O --global
+       run_compiler "nitc-g" ../src/nitc_3 -O --global
        prepare_res "$name-nitg.dat" "nitg" "nitg"
        run_compiler "nitg" ./nitg
        prepare_res "$name-nitg-s.dat" "nitg-s" "nitg with --separate"
@@ -432,11 +345,11 @@ function bench_nitc_vc_nitg-e()
        name="$FUNCNAME"
        skip_test "$name" && return
        prepare_res "$name-nitc.dat" "nitc" "nitc"
-       run_compiler "nitc" ./nitc_3 -O
+       run_compiler "nitc" ../src/nitc_3 -O
        prepare_res "$name-nitc-malloc.dat" "nitc-malloc" "nitc with malloc"
-       NIT_GC_OPTION="malloc" run_compiler "nitc" ./nitc_3 -O
+       NIT_GC_OPTION="malloc" run_compiler "nitc" ../src/nitc_3 -O
        prepare_res "$name-nitc-bohem.dat" "nitc-boehm" "nitc with boehm"
-       NIT_GC_OPTION="boehm" run_compiler "nitc" ./nitc_3 -O
+       NIT_GC_OPTION="boehm" run_compiler "nitc" ../src/nitc_3 -O
        prepare_res "$name-nitg-e-nockeck-malloc.dat" "nitg-e-nc-malloc" "nitg with --erasure --no-check-autocast --no-check-erasure-cast and malloc"
        run_compiler "nitg-e-nc-malloc" ./nitg --erasure --no-check-autocast --no-check-erasure-cast --make-flags "CFLAGS=\"-O2 -DNOBOEHM\""
        prepare_res "$name-nitg-e-nockeck.dat" "nitg-e-nc" "nitg with --erasure --no-check-autocast --no-check-erasure-cast"
@@ -496,114 +409,21 @@ function bench_compilation_time
        name="$FUNCNAME"
        skip_test "$name" && return
        prepare_res "$name-nitc.dat" "nitc" "nitc"
-       for i in ../examples/hello_world.nit test_parser.nit nitg.nit; do
-               bench_command `basename "$i" .nit` "" ./nitc_3 -O "$i" --no-cc
+       for i in ../examples/hello_world.nit ../src/test_parser.nit ../src/nitg.nit; do
+               bench_command `basename "$i" .nit` "" ../src/nitc_3 -O "$i" --no-cc
        done
        prepare_res "$name-nitg.dat" "nitg" "nitg"
-       for i in ../examples/hello_world.nit test_parser.nit nitg.nit; do
+       for i in ../examples/hello_world.nit ../src/test_parser.nit ../src/nitg.nit; do
                bench_command `basename "$i" .nit` "" ./nitg "$i" --no-cc
        done
        prepare_res "$name-nitg-e.dat" "nitg-e" "nitg --erasure"
-       for i in ../examples/hello_world.nit test_parser.nit nitg.nit; do
+       for i in ../examples/hello_world.nit ../src/test_parser.nit ../src/nitg.nit; do
                bench_command `basename "$i" .nit` "" ./nitg --erasure "$i" --no-cc
        done
        plot "$name.gnu"
 }
 bench_compilation_time
 
-function bench_typetest_languages()
-{
-       name="$FUNCNAME"
-       skip_test "$name" && return
-
-       t=t
-       s=20
-       seq="w2_h2 w50_h2 w2_h25 w50_h25"
-       for b in $seq; do
-               run_command ./nitg benchs/gen.nit
-               run_command ./gen.bin "${t}_$b" "$b"
-       done
-
-       prepare_res "$name-g++.dat" "g++" "g++"
-       for b in $seq; do
-               run_command g++ "${t}_$b.cpp" -O2 -o "${t}_$b.g++.bin"
-               bench_command "$b" "" "./${t}_$b.g++.bin" $s
-       done
-
-       prepare_res "$name-clang++.dat" "clang++" "clang++"
-       for b in $seq; do
-               run_command clang++ "${t}_$b.cpp" -O2 -o "${t}_$b.clang++.bin"
-               bench_command "$b" "" "./${t}_$b.clang++.bin" $s
-       done
-
-       prepare_res "$name-java.dat" "java" "java"
-       for b in $seq; do
-               run_command javac ${t}_$b.java
-               bench_command "$b" "" java "${t}_$b" $s
-       done
-
-       prepare_res "$name-scala.dat" "scala" "scala"
-       for b in $seq; do
-               run_command scalac ${t}_$b.scala
-               bench_command "$b" "" scala "${t}_$b" $s
-       done
-
-       prepare_res "$name-cs.dat" "c#" "c#"
-       for b in $seq; do
-               run_command gmcs ${t}_$b.cs
-               bench_command "$b" "" mono "${t}_$b.exe" $s
-       done
-
-       prepare_res "$name-es.dat" "es" "es"
-       for b in $seq; do
-               run_command ec -clean -finalize ${t}_$b/app${t}_$b.e
-               chmod +x app${t}_$b
-               mv app${t}_$b  ${t}_$b.es.bin
-               bench_command "$b" "" "./${t}_$b.es.bin" $s
-       done
-
-       prepare_res "$name-se.dat" "se" "se"
-       for b in $seq; do
-               run_command se compile -no_check app${t}_${b}_se.e -loadpath ${t}_${b}_se -o ${t}_$b.se.bin
-               bench_command "$b" "" "./${t}_$b.se.bin" $s
-       done
-
-       #too slow
-       #prepare_res "$name-nitg.dat" "nitg" "nitg"
-       #for b in $seq; do
-       #       run_command ./nitg "${t}_$b.nit" -o "${t}_$b.nitg.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
-       #       bench_command "$b" "" "./${t}_$b.nitg.bin" $s
-       #done
-
-       prepare_res "$name-nitg-s.dat" "nitg-s" "nitg-s"
-       for b in $seq; do
-               run_command ./nitg ${t}_$b.nit --separate -o "${t}_$b.nitg-s.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
-               bench_command "$b" "" "./${t}_$b.nitg-s.bin" $s
-       done
-
-       prepare_res "$name-nitg-su.dat" "nitg-su" "nitg-su"
-       for b in $seq; do
-               run_command ./nitg ${t}_$b.nit --separate --no-check-covariance -o "${t}_$b.nitg-su.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
-               bench_command "$b" "" "./${t}_$b.nitg-su.bin" $s
-       done
-
-
-       prepare_res "$name-nitg-e.dat" "nitg-e" "nitg-e"
-       for b in $seq; do
-               run_command ./nitg ${t}_$b.nit --erasure -o "${t}_$b.nitg-e.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
-               bench_command "$b" "" "./${t}_$b.nitg-e.bin" $s
-       done
-
-       prepare_res "$name-nitg-eu.dat" "nitg-eu" "nitg-eu"
-       for b in $seq; do
-               run_command ./nitg ${t}_$b.nit --erasure --no-check-covariance --no-check-erasure-cast -o "${t}_$b.nitg-eu.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
-               bench_command "$b" "" "./${t}_$b.nitg-eu.bin" $s
-       done
-
-       plot "$name.gnu"
-}
-bench_typetest_languages
-
 if test -n "$died"; then
        echo "Some commands failed"
        exit 1
diff --git a/benchmarks/bench_languages.sh b/benchmarks/bench_languages.sh
new file mode 100755 (executable)
index 0000000..8316ab9
--- /dev/null
@@ -0,0 +1,588 @@
+#!/bin/bash
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This shell script helps running benchmarks
+
+# TODO: cleanup and libify the helper-parts
+
+source ./bench_plot.sh
+
+## CONFIGURATION OPTIONS ##
+
+# Default number of times a command must be run with bench_command
+# Can be overrided with 'the option -n'
+count=2
+
+### HELPER FUNCTIONS ##
+
+function die()
+{
+       echo >&2 "error: $*"
+       died=1
+}
+
+# Run a single command multiple time and store the execution times
+# in the current $res file.
+#
+#  $1: title of the command
+#  $2: long desription of the command
+#  rest: the command to execute
+function bench_command()
+{
+       if [ "$dry_run" = "true" ]; then return; fi
+       local title="$1"
+       local desc="$2"
+       shift
+       shift
+       if test "$verbose" = true; then outputopts="/dev/stdout"; else outputopts="/dev/null"; fi
+       timeout="time.out"
+       echo "$title" > "$timeout"
+       echo "# $desc" >> "$timeout"
+       echo "\$ $@" >> "$timeout"
+       echo
+       echo "** [$title] $desc **"
+       echo " $ $@"
+
+       # Execute the commands $count times
+       for i in `seq 1 "$count"`; do
+               /usr/bin/time -f "%U" -o "$timeout" -a "$@" > $outputopts 2>&1 || die "$1: failed"
+               echo -n "$i. "
+               tail -n 1 "$timeout"
+       done
+
+       line=`compute_stats "$timeout"`
+       echo "$line ($res)"
+       echo $line >> "$res"
+       rm $timeout
+}
+
+# Run a simple command witout storing the execution time
+# Used to display command on verbose and skip long executions when dry_run is given
+# $@ command to execute
+function run_command()
+{
+       if [ "$dry_run" = "true" ]; then return; fi
+       echo " $ $@"
+       "$@" || die "$@: failed"
+}
+
+# Check if the test should be skiped according to its name
+# $1: name of the test
+# $2: description of the test
+# $NOTSKIPED: arguments
+function skip_test()
+{
+       if test -z "$NOTSKIPED"; then
+               echo "* $1"
+               return 0
+       fi
+       if test "$NOTSKIPED" = "all"; then
+               : # Execute anyway
+       elif echo "$1" | egrep "$NOTSKIPED" >/dev/null 2>&1; then
+               : # Found one to execute
+       else
+               return 0
+       fi
+       echo "*"
+       echo "* $1 *****"
+       echo "*"
+       return 1
+}
+
+## HANDLE OPTIONS ##
+
+function usage()
+{
+       echo "run_bench: [options]* benchname"
+       echo "  -v: verbose mode"
+       echo "  -n count: number of execution for each bar (default: $count)"
+       echo "  --dry: Do not run the commands, just reuse the data and generate the graph"
+       echo "  --fast: Run less and faster tests"
+       echo "  -h: this help"
+}
+
+stop=false
+while [ "$stop" = false ]; do
+       case "$1" in
+               -v) verbose=true; shift;;
+               -h) usage; exit;;
+               -n) count="$2"; shift; shift;;
+               --dry) dry_run=true; shift;;
+               --fast) fast=true; shift;;
+               *) stop=true
+       esac
+done
+
+NOTSKIPED="$*"
+
+if test -z "$NOTSKIPED"; then
+       usage
+       echo "List of available benches:"
+       echo "* all: run all the benches"
+fi
+
+## COMPILE ENGINES
+cd ../src
+test -f ./nitc_3 || ./ncall.sh -O
+cd ../benchmarks
+test -f ./nitg || ../src/nitc_3 ../src/nitg.nit -O -v
+
+## EFFECTIVE BENCHS ##
+
+function bench_typetest_languages()
+{
+       name="$FUNCNAME"
+       skip_test "$name" && return
+
+       t=t
+       s=20
+       seq="w2_h2 w50_h2 w2_h25 w50_h25"
+       for b in $seq; do
+               run_command ./nitg languages/gen.nit
+               run_command ./gen.bin "${t}_$b" "$b"
+       done
+
+       prepare_res "$name-g++.dat" "g++" "g++"
+       for b in $seq; do
+               run_command g++ "${t}_$b.cpp" -O2 -o "${t}_$b.g++.bin"
+               bench_command "$b" "" "./${t}_$b.g++.bin" $s
+       done
+
+       prepare_res "$name-clang++.dat" "clang++" "clang++"
+       for b in $seq; do
+               run_command clang++ "${t}_$b.cpp" -O2 -o "${t}_$b.clang++.bin"
+               bench_command "$b" "" "./${t}_$b.clang++.bin" $s
+       done
+
+       prepare_res "$name-java.dat" "java" "java"
+       for b in $seq; do
+               run_command javac ${t}_$b.java
+               bench_command "$b" "" java "${t}_$b" $s
+       done
+
+       prepare_res "$name-scala.dat" "scala" "scala"
+       for b in $seq; do
+               run_command scalac ${t}_$b.scala
+               bench_command "$b" "" scala "${t}_$b" $s
+       done
+
+       prepare_res "$name-cs.dat" "c#" "c#"
+       for b in $seq; do
+               run_command gmcs ${t}_$b.cs
+               bench_command "$b" "" mono "${t}_$b.exe" $s
+       done
+
+       prepare_res "$name-es.dat" "es" "es"
+       for b in $seq; do
+               run_command ec -clean -finalize ${t}_$b/app${t}_$b.e
+               chmod +x app${t}_$b
+               mv app${t}_$b  ${t}_$b.es.bin
+               bench_command "$b" "" "./${t}_$b.es.bin" $s
+       done
+
+       prepare_res "$name-se.dat" "se" "se"
+       for b in $seq; do
+               run_command se compile -no_check app${t}_${b}_se.e -loadpath ${t}_${b}_se -o ${t}_$b.se.bin
+               bench_command "$b" "" "./${t}_$b.se.bin" $s
+       done
+
+       #too slow
+       #prepare_res "$name-nitg.dat" "nitg" "nitg"
+       #for b in $seq; do
+       #       run_command ./nitg "${t}_$b.nit" -o "${t}_$b.nitg.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+       #       bench_command "$b" "" "./${t}_$b.nitg.bin" $s
+       #done
+
+       prepare_res "$name-nitg-s.dat" "nitg-s" "nitg-s"
+       for b in $seq; do
+               run_command ./nitg ${t}_$b.nit --separate -o "${t}_$b.nitg-s.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "./${t}_$b.nitg-s.bin" $s
+       done
+
+       prepare_res "$name-nitg-su.dat" "nitg-su" "nitg-su"
+       for b in $seq; do
+               run_command ./nitg ${t}_$b.nit --separate --no-check-covariance -o "${t}_$b.nitg-su.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "./${t}_$b.nitg-su.bin" $s
+       done
+
+
+       prepare_res "$name-nitg-e.dat" "nitg-e" "nitg-e"
+       for b in $seq; do
+               run_command ./nitg ${t}_$b.nit --erasure -o "${t}_$b.nitg-e.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "./${t}_$b.nitg-e.bin" $s
+       done
+
+       prepare_res "$name-nitg-eu.dat" "nitg-eu" "nitg-eu"
+       for b in $seq; do
+               run_command ./nitg ${t}_$b.nit --erasure --no-check-covariance --no-check-erasure-cast -o "${t}_$b.nitg-eu.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "./${t}_$b.nitg-eu.bin" $s
+       done
+
+       plot "$name.gnu"
+}
+bench_typetest_languages
+
+function bench_typetest_depth()
+{
+       name="$FUNCNAME"
+       skip_test "$name" && return
+       rootdir=`pwd`
+       basedir="./${name}.out"
+
+       mkdir $basedir
+
+       t=t
+       s=20
+       seq="10 25 50 100"
+       for b in $seq; do
+               run_command ./nitg languages/$name.nit -o $basedir/$name.bin
+               run_command $basedir/$name.bin $basedir "${t}_$b" "$b"
+       done
+
+       prepare_res $basedir/$name-g++.dat "g++" "g++"
+       cppdir="${basedir}/cpp"
+       for b in $seq; do
+               run_command g++ "${cppdir}/${t}_$b.cpp" -O2 -o "${cppdir}/${t}_$b.g++.bin"
+               bench_command "$b" "" "${cppdir}/${t}_$b.g++.bin" $s
+       done
+
+       prepare_res $basedir/$name-clang++.dat "clang++" "clang++"
+       for b in $seq; do
+               run_command clang++ "${cppdir}/${t}_$b.cpp" -O2 -o "${cppdir}/${t}_$b.clang++.bin"
+               bench_command "$b" "" "${cppdir}/${t}_$b.clang++.bin" $s
+       done
+
+       prepare_res $basedir/$name-java.dat "java" "java"
+       javadir="${basedir}/java"
+       for b in $seq; do
+               run_command javac "${javadir}/${t}_$b.java"
+               bench_command "$b" "" java -cp "${javadir}/" "${t}_$b" $s
+       done
+
+       prepare_res $basedir/$name-scala.dat "scala" "scala"
+       scaladir="${basedir}/scala"
+       for b in $seq; do
+               run_command scalac "${scaladir}/${t}_$b.scala" -d "${scaladir}"
+               bench_command "$b" "" scala -cp "${scaladir}/" "${t}_$b" $s
+       done
+
+       prepare_res $basedir/$name-cs.dat "c#" "c#"
+       csdir="${basedir}/cs"
+       for b in $seq; do
+               run_command gmcs "$csdir/${t}_$b.cs"
+               bench_command "$b" "" mono "$csdir/${t}_$b.exe" $s
+       done
+
+       prepare_res $basedir/$name-es.dat "es" "es"
+       esdir="${basedir}/es"
+       for b in $seq; do
+               cd $esdir
+               run_command ec -clean -finalize ${t}_$b/app${t}_$b.e
+               chmod +x app${t}_$b
+               mv app${t}_$b ${t}_$b.es.bin
+               cd $rootdir
+               bench_command "$b" "" "$esdir/${t}_$b.es.bin" $s
+       done
+
+       prepare_res $basedir/$name-se.dat "se" "se"
+       sedir="${basedir}/se"
+       for b in $seq; do
+               cd $sedir
+               run_command se compile -no_check app${t}_${b}_se.e -loadpath ${t}_${b}_se -o ${t}_$b.se.bin
+               cd $rootdir
+               bench_command "$b" "" "$sedir/${t}_$b.se.bin" $s
+       done
+
+       nitdir="${basedir}/nit"
+       prepare_res $nitdir/$name-nitg.dat "nitg" "nitg"
+       for b in $seq; do
+               run_command ./nitg $nitdir/${t}_$b.nit -o "$nitdir/${t}_$b.nitg.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "$nitdir/${t}_$b.nitg.bin" $s
+       done
+
+       prepare_res $nitdir/$name-nitg-s.dat "nitg-s" "nitg-s"
+       for b in $seq; do
+               run_command ./nitg $nitdir/${t}_$b.nit --separate -o "$nitdir/${t}_$b.nitg-s.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "$nitdir/${t}_$b.nitg-s.bin" $s
+       done
+
+       prepare_res $nitdir/$name-nitg-su.dat "nitg-su" "nitg-su"
+       for b in $seq; do
+               run_command ./nitg $nitdir/${t}_$b.nit --separate --no-check-covariance -o "$nitdir/${t}_$b.nitg-su.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "$nitdir/${t}_$b.nitg-su.bin" $s
+       done
+
+       prepare_res $nitdir/$name-nitg-e.dat "nitg-e" "nitg-e"
+       for b in $seq; do
+               run_command ./nitg $nitdir/${t}_$b.nit --erasure -o "$nitdir/${t}_$b.nitg-e.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "$nitdir/${t}_$b.nitg-e.bin" $s
+       done
+
+       prepare_res $nitdir/$name-nitg-eu.dat "nitg-eu" "nitg-eu"
+       for b in $seq; do
+               run_command ./nitg $nitdir/${t}_$b.nit --erasure --no-check-covariance --no-check-erasure-cast -o "$nitdir/${t}_$b.nitg-eu.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "$nitdir/${t}_$b.nitg-eu.bin" $s
+       done
+
+       plot $basedir/$name.gnu
+}
+bench_typetest_depth
+
+function bench_typetest_fts_depth()
+{
+       name="$FUNCNAME"
+       skip_test "$name" && return
+       rootdir=`pwd`
+       basedir="./${name}.out"
+
+       mkdir $basedir
+
+       t=t
+       s=20
+       seq="10 25 50 100"
+       for b in $seq; do
+               run_command ./nitg languages/$name.nit -o $basedir/$name.bin
+               run_command $basedir/$name.bin $basedir "${t}_$b" "$b"
+       done
+
+       prepare_res $basedir/$name-cs.dat "c#" "c#"
+       csdir="${basedir}/cs"
+       for b in $seq; do
+               run_command gmcs "$csdir/${t}_$b.cs"
+               bench_command "$b" "" mono "$csdir/${t}_$b.exe" $s
+       done
+
+       prepare_res $basedir/$name-es.dat "es" "es"
+       esdir="${basedir}/es"
+       for b in $seq; do
+               cd $esdir
+               run_command ec -clean -finalize ${t}_$b/app${t}_$b.e
+               chmod +x app${t}_$b
+               mv app${t}_$b ${t}_$b.es.bin
+               cd $rootdir
+               bench_command "$b" "" "$esdir/${t}_$b.es.bin" $s
+       done
+
+       prepare_res $basedir/$name-se.dat "se" "se"
+       sedir="${basedir}/se"
+       for b in $seq; do
+               cd $sedir
+               run_command se compile -no_check app${t}_${b}_se.e -loadpath ${t}_${b}_se -o ${t}_$b.se.bin
+               cd $rootdir
+               bench_command "$b" "" "$sedir/${t}_$b.se.bin" $s
+       done
+
+       nitdir="${basedir}/nit"
+       prepare_res $nitdir/$name-nitg.dat "nitg" "nitg"
+       for b in $seq; do
+               run_command ./nitg $nitdir/${t}_$b.nit -o "$nitdir/${t}_$b.nitg.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "$nitdir/${t}_$b.nitg.bin" $s
+       done
+
+       prepare_res $nitdir/$name-nitg-s.dat "nitg-s" "nitg-s"
+       for b in $seq; do
+               run_command ./nitg $nitdir/${t}_$b.nit --separate -o "$nitdir/${t}_$b.nitg-s.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "$nitdir/${t}_$b.nitg-s.bin" $s
+       done
+
+       prepare_res $nitdir/$name-nitg-su.dat "nitg-su" "nitg-su"
+       for b in $seq; do
+               run_command ./nitg $nitdir/${t}_$b.nit --separate --no-check-covariance -o "$nitdir/${t}_$b.nitg-su.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "$nitdir/${t}_$b.nitg-su.bin" $s
+       done
+
+       prepare_res $nitdir/$name-nitg-e.dat "nitg-e" "nitg-e"
+       for b in $seq; do
+               run_command ./nitg $nitdir/${t}_$b.nit --erasure -o "$nitdir/${t}_$b.nitg-e.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "$nitdir/${t}_$b.nitg-e.bin" $s
+       done
+
+       prepare_res $nitdir/$name-nitg-eu.dat "nitg-eu" "nitg-eu"
+       for b in $seq; do
+               run_command ./nitg $nitdir/${t}_$b.nit --erasure --no-check-covariance --no-check-erasure-cast -o "$nitdir/${t}_$b.nitg-eu.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "$nitdir/${t}_$b.nitg-eu.bin" $s
+       done
+
+       plot $basedir/$name.gnu
+}
+bench_typetest_fts_depth
+
+function bench_typetest_fts_width()
+{
+       name="$FUNCNAME"
+       skip_test "$name" && return
+       rootdir=`pwd`
+       basedir="./${name}.out"
+
+       mkdir $basedir
+
+       t=t
+       s=20
+       depth=10
+       seq="1 2 5 10"
+       for b in $seq; do
+               run_command ./nitg languages/$name.nit -o $basedir/$name.bin
+               run_command $basedir/$name.bin $basedir "${t}_$b" $depth $b
+       done
+
+       prepare_res $basedir/$name-cs.dat "c#" "c#"
+       csdir="${basedir}/cs"
+       for b in $seq; do
+               run_command gmcs "$csdir/${t}_$b.cs"
+               bench_command "$b" "" mono "$csdir/${t}_$b.exe" $s
+       done
+
+       prepare_res $basedir/$name-es.dat "es" "es"
+       esdir="${basedir}/es"
+       for b in $seq; do
+               cd $esdir
+               run_command ec -clean -finalize ${t}_$b/app${t}_$b.e
+               chmod +x app${t}_$b
+               mv app${t}_$b ${t}_$b.es.bin
+               cd $rootdir
+               bench_command "$b" "" "$esdir/${t}_$b.es.bin" $s
+       done
+
+       prepare_res $basedir/$name-se.dat "se" "se"
+       sedir="${basedir}/se"
+       for b in $seq; do
+               cd $sedir
+               run_command se compile -no_check app${t}_${b}_se.e -loadpath ${t}_${b}_se -o ${t}_$b.se.bin
+               cd $rootdir
+               bench_command "$b" "" "$sedir/${t}_$b.se.bin" $s
+       done
+
+       nitdir="${basedir}/nit"
+
+       prepare_res $nitdir/$name-nitg.dat "nitg" "nitg"
+       for b in $seq; do
+               run_command ./nitg $nitdir/${t}_$b.nit -o "$nitdir/${t}_$b.nitg.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "$nitdir/${t}_$b.nitg.bin" $s
+       done
+
+       prepare_res $nitdir/$name-nitg-s.dat "nitg-s" "nitg-s"
+       for b in $seq; do
+               run_command ./nitg $nitdir/${t}_$b.nit --separate -o "$nitdir/${t}_$b.nitg-s.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "$nitdir/${t}_$b.nitg-s.bin" $s
+       done
+
+       prepare_res $nitdir/$name-nitg-su.dat "nitg-su" "nitg-su"
+       for b in $seq; do
+               run_command ./nitg $nitdir/${t}_$b.nit --separate --no-check-covariance -o "$nitdir/${t}_$b.nitg-su.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "$nitdir/${t}_$b.nitg-su.bin" $s
+       done
+
+       prepare_res $nitdir/$name-nitg-e.dat "nitg-e" "nitg-e"
+       for b in $seq; do
+               run_command ./nitg $nitdir/${t}_$b.nit --erasure -o "$nitdir/${t}_$b.nitg-e.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "$nitdir/${t}_$b.nitg-e.bin" $s
+       done
+
+       prepare_res $nitdir/$name-nitg-eu.dat "nitg-eu" "nitg-eu"
+       for b in $seq; do
+               run_command ./nitg $nitdir/${t}_$b.nit --erasure --no-check-covariance --no-check-erasure-cast -o "$nitdir/${t}_$b.nitg-eu.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "$nitdir/${t}_$b.nitg-eu.bin" $s
+       done
+
+       plot $basedir/$name.gnu
+}
+bench_typetest_fts_width
+
+function bench_typetest_fts_nesting()
+{
+       name="$FUNCNAME"
+       skip_test "$name" && return
+       rootdir=`pwd`
+       basedir="./${name}.out"
+
+       mkdir $basedir
+
+       t=t
+       s=20
+       depth=5
+       seq="1 2 5 10"
+       for b in $seq; do
+               run_command ./nitg languages/$name.nit -o $basedir/$name.bin
+               run_command $basedir/$name.bin $basedir "${t}_$b" $depth $b
+       done
+
+       prepare_res $basedir/$name-cs.dat "c#" "c#"
+       csdir="${basedir}/cs"
+       for b in $seq; do
+               run_command gmcs "$csdir/${t}_$b.cs"
+               bench_command "$b" "" mono "$csdir/${t}_$b.exe" $s
+       done
+
+       prepare_res $basedir/$name-es.dat "es" "es"
+       esdir="${basedir}/es"
+       for b in $seq; do
+               cd $esdir
+               run_command ec -clean -finalize ${t}_$b/app${t}_$b.e
+               chmod +x app${t}_$b
+               mv app${t}_$b ${t}_$b.es.bin
+               cd $rootdir
+               bench_command "$b" "" "$esdir/${t}_$b.es.bin" $s
+       done
+
+       prepare_res $basedir/$name-se.dat "se" "se"
+       sedir="${basedir}/se"
+       for b in $seq; do
+               cd $sedir
+               run_command se compile -no_check app${t}_${b}_se.e -loadpath ${t}_${b}_se -o ${t}_$b.se.bin
+               cd $rootdir
+               bench_command "$b" "" "$sedir/${t}_$b.se.bin" $s
+       done
+
+       nitdir="${basedir}/nit"
+
+       prepare_res $nitdir/$name-nitg.dat "nitg" "nitg"
+       for b in $seq; do
+               run_command ./nitg $nitdir/${t}_$b.nit -o "$nitdir/${t}_$b.nitg.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "$nitdir/${t}_$b.nitg.bin" $s
+       done
+
+       prepare_res $nitdir/$name-nitg-s.dat "nitg-s" "nitg-s"
+       for b in $seq; do
+               run_command ./nitg $nitdir/${t}_$b.nit --separate -o "$nitdir/${t}_$b.nitg-s.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "$nitdir/${t}_$b.nitg-s.bin" $s
+       done
+
+       prepare_res $nitdir/$name-nitg-su.dat "nitg-su" "nitg-su"
+       for b in $seq; do
+               run_command ./nitg $nitdir/${t}_$b.nit --separate --no-check-covariance -o "$nitdir/${t}_$b.nitg-su.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "$nitdir/${t}_$b.nitg-su.bin" $s
+       done
+
+       prepare_res $nitdir/$name-nitg-e.dat "nitg-e" "nitg-e"
+       for b in $seq; do
+               run_command ./nitg $nitdir/${t}_$b.nit --erasure -o "$nitdir/${t}_$b.nitg-e.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "$nitdir/${t}_$b.nitg-e.bin" $s
+       done
+
+       prepare_res $nitdir/$name-nitg-eu.dat "nitg-eu" "nitg-eu"
+       for b in $seq; do
+               run_command ./nitg $nitdir/${t}_$b.nit --erasure --no-check-covariance --no-check-erasure-cast -o "$nitdir/${t}_$b.nitg-eu.bin" --make-flags "CFLAGS=\"-g -O2 -DNOBOEHM\""
+               bench_command "$b" "" "$nitdir/${t}_$b.nitg-eu.bin" $s
+       done
+
+       plot $basedir/$name.gnu
+}
+bench_typetest_fts_nesting
+
+if test -n "$died"; then
+       echo "Some commands failed"
+       exit 1
+fi
+exit 0
diff --git a/benchmarks/bench_plot.sh b/benchmarks/bench_plot.sh
new file mode 100755 (executable)
index 0000000..0c7d36b
--- /dev/null
@@ -0,0 +1,106 @@
+#!/bin/bash
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This shell script generate gnuplot results
+
+# perl function to compute min/max/avg.
+# used by bench_command
+#
+# $1: file
+# return: first min max avg label
+function compute_stats()
+{
+       file="$1"
+       # Compute statistics
+       perl - "$file" <<'END'
+       @lines = ();
+       $first = undef;
+       chomp($label = <>);
+       while(<>) {
+               chomp;
+               if (/^\d/) {
+                       if (defined $first) {
+                               push @lines, $_;
+                       } else {
+                               $first = $_;
+                       }
+               }
+       }
+       $len = scalar @lines;
+       if ($len) {
+               @lines = sort {$a <=> $b} @lines;
+               $min = $lines[0];
+               $max = $lines[$#lines];
+               $avg = 0;
+               for $i (@lines) { $avg += $i; }
+               $avg = $avg / $len;
+               print "${first} ${min} ${max} ${avg} \"${label}\"\n";
+       } else {
+               print "${first} ${first} ${first} ${first} \"${label}\"\n";
+       }
+END
+}
+
+# Create a new $res to be used in the next plot
+#
+# $1 = resfile
+# $2 = title
+# $3 = description
+function prepare_res()
+{
+       echo
+       echo "# [$2] $3 #"
+       res=$1
+       if [ "$plots" = "" ]; then
+               plots="plot '$1' using 4:2:3:xticlabels(5) ti '$2';"
+       else
+               plots="$plots replot '$1' using 4:2:3 ti '$2';"
+       fi
+       if [ "$dry_run" = "true" ]; then return; fi
+       echo "# [$2] $3 ; count=$count" > "$res"
+       echo "# first min max avg title" >> "$res"
+}
+
+# Plot the last $res as an histogram
+# $1: plot file (eg toto.gnu)
+function plot()
+{
+       cat >"$1" <<END
+set auto x;
+set yrange [0:];
+set style data histogram;
+set style histogram cluster gap 2;
+set style histogram errorbars linewidth 1;
+set style fill solid 0.3 border -1;
+set bars front;
+set boxwidth 0.9;
+set xtic nomirror rotate by -45 scale 0 font ',8';
+set title "$1 ; avg. on $count-1 runs"
+set ylabel "time (s)"
+$plots
+END
+       echo "# gnuplot -p $1"
+       gnuplot -p "$1"
+       plots=
+}
+
+## GLOBAL VARIABLES ##
+
+# The current $res (set by prepare_res, used by bench_command)
+res=
+
+# The current stuff to plot (set by prepare_res, used by plot)
+plots=
+
diff --git a/benchmarks/languages/bench_typetest_depth.nit b/benchmarks/languages/bench_typetest_depth.nit
new file mode 100644 (file)
index 0000000..7e4cd43
--- /dev/null
@@ -0,0 +1,394 @@
+#!/usr/bin/env nit
+
+# Microbenchmak generation for multiple language
+# Just a quick an dirty Nit script file :)
+
+# This benchmark focuses on effects of the hierarchy dept
+# on the typetest performances
+
+# 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 = 10000
+       var middle = 0
+
+       fun genhier
+       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
+               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)
+       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 "var a:{classes.first}[Root] = new {classes.last}[Root]"
+               write "var x = 0"
+               write "for i in [0..{loops}[ do"
+               write "\tfor j in [0..{loops}[ do"
+               write "\t\tif a isa {classes[middle]}[Root] then x += 1"
+               write "\tend"
+               write "end"
+               write "print x"
+
+               file.close
+       end
+
+       fun writejava(dir: String, name: String, interfaces: Bool)
+       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[]) \{"
+               if interfaces then
+                       write "\t{classes.first}<Root> a = new X{classes.last}<Root>();"
+                       write "\t{classes.first}<Root> b = new X{classes.last}<Root>();"
+               else
+                       write "\t{classes.first}<Root> a = new {classes.last}<Root>();"
+                       write "\t{classes.first}<Root> b = new X{classes.last}<Root>();"
+               end
+               write "\ttest(a, b);"
+               write "\}"
+
+               write "static public void test({classes.first}<Root> a, {classes.first}<Root> b) \{"
+               write "\tint x = 0;"
+               write "\tfor(int i = 0; i < {loops}; i++) \{"
+               write "\t\tfor(int j = 0; j < {loops}; j++) \{"
+               write "\t\t\tif(a instanceof {classes[middle]}) \{ x++; \} else \{ 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)
+       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
+
+               write "static void Main(string[] args) \{"
+               if interfaces then
+                       write "\t{classes.first}<Root> a = new X{classes.last}<Root>();"
+                       write "\t{classes.first}<Root> b = new X{classes.last}<Root>();"
+               else
+                       write "\t{classes.first}<Root> a = new {classes.last}<Root>();"
+                       write "\t{classes.first}<Root> b = new {classes.last}<Root>();"
+               end
+               write "\tTest(a, b);"
+               write "\}"
+
+               write "static void Test({classes.first}<Root> a, {classes.first}<Root> b) \{"
+               write "\tint x = 0;"
+               write "\tfor(int i = 0; i < {loops}; i++) \{"
+               write "\t\tfor(int j = 0; j < {loops}; j++) \{"
+               write "\t\t\tif(a is {classes[middle]}<Root>) \{ x++; \} else \{ 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)
+       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
+
+               write "def main(args: Array[String]) = \{"
+               if interfaces then
+                       write "\tvar a:{classes.first}[Root] = new X{classes.last}[Root]()"
+                       write "\tvar b:{classes.first}[Root] = new X{classes.last}[Root]()"
+               else
+                       write "\tvar a:{classes.first}[Root] = new {classes.last}[Root]()"
+                       write "\tvar b:{classes.first}[Root] = new {classes.last}[Root]()"
+               end
+               write "\ttest(a, b)"
+               write "\}"
+
+               write "def test(a:{classes.first}[Root], b:{classes.first}[Root]) = \{"
+               write "\tvar o = a"
+               write "\tvar x = 0"
+               write "\tfor (i <- 0 to {loops}) \{"
+               write "\t\tfor (j <- 0 to {loops}) \{"
+               write "\t\tif (o.isInstanceOf[{classes[middle]}[Root]]) \{ x = x + 1 \} else \{ o = b \}"
+               write "\t\t\}"
+               write "\t\}"
+               write "\t\t\tprintln(x)"
+               write "\}"
+               write "\}"
+
+               file.close
+       end
+
+       fun writecpp(dir: String, name: String)
+       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({classes.first}<Root>* a, {classes.first}<Root>* b) \{"
+               write "\tint x = 0;"
+               write "\tfor(int i = 0; i < {loops}; i++) \{"
+               write "\t\tfor(int j = 0; j < {loops}; j++) \{"
+               write "\t\t\t{classes[middle]}<Root>* to = dynamic_cast<{classes[middle]}<Root>*>(a);"
+               write "\t\tif(to != 0) \{ x++; \} else \{ a = b; \}"
+               write "\t\t}"
+               write "\t\}"
+               write "\tstd::cout << x << std::endl;"
+               write "\}"
+
+               write "int main(int argc, char **argv) \{"
+               write "\t{classes.first}<Root>* a = new {classes.first}<Root>();"
+               write "\t{classes.first}<Root>* b = new {classes.first}<Root>();"
+               write "\ttest(a, b);"
+               write "\}"
+
+               file.close
+       end
+
+       fun writee(dir: String, name: String, se: Bool)
+       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
+
+               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"
+               end
+               write "create make"
+               write "feature"
+
+               if se then
+                       write "\tmake{istk}"
+               else
+                       write "\tmake(args: ARRAY[STRING]){istk}"
+               end
+               write "\t\tlocal"
+               write "\t\t\ta: {classes.first}[ROOT]"
+               write "\t\t\tb: {classes.first}[ROOT]"
+               write "\t\tdo"
+               write "\t\t\tcreate \{{classes.last}[ROOT]\} a"
+               write "\t\t\tcreate \{{classes.last}[ROOT]\} b"
+               write "\t\t\ttest(a, b)"
+               write "\t\tend"
+
+               write "\ttest(a: {classes.first}[ROOT]; b: {classes.first}[ROOT]){istk}"
+               write "\t\tlocal"
+               write "\t\t\to: {classes.first}[ROOT]"
+               write "\t\t\tto: {classes[middle]}[ROOT]"
+               write "\t\t\ti: INTEGER"
+               write "\t\t\tj: INTEGER"
+               write "\t\t\tx: INTEGER"
+               write "\t\tdo"
+               write "\t\t\to := a"
+               write "\t\t\tfrom i := 0 until i>={loops} loop"
+               write "\t\t\t\tfrom j := 0 until j>={loops} loop"
+               write "\t\t\t\t\tto ?= o"
+               write "\t\t\t\t\tif to /= Void then x := x + 1 else 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)
diff --git a/src/benchs/gen.nit b/src/benchs/gen.nit
deleted file mode 100644 (file)
index 9dc2d32..0000000
+++ /dev/null
@@ -1,666 +0,0 @@
-#!/usr/bin/env nit
-
-# Microbenchmak generation for multiple language
-# Just a quick an dirty Nit script file :)
-
-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 width = 5
-       var height = 5
-       var superprobs: Array[Int] = [40, 20, 5]
-
-       fun genhier
-       do
-               var i = 0
-               for w in [0..width[ do
-                       var s: nullable Klass = null
-                       for h in [0..height[ do
-                               i += 1
-                               var c = new Klass(i)
-
-                               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
-                       end
-               end
-
-               for j in [0..listlen[ do
-                       var c = classes[classes.length - 1 - (j % classes.length)]
-                       list.unshift(c)
-                       unlist.push(c)
-               end
-       end
-
-       # List of instantited class in the order to read
-       var list = new List[Klass]
-
-       # List of instantited class in the order to push
-       var unlist = new List[Klass]
-
-       var arraylen = 2000
-       var loops = 10000
-
-       var listlen = 50
-
-       var file: nullable OFStream = null
-       fun write(str: String)
-       do
-               file.write(str)
-               file.write("\n")
-       end
-
-       fun writenit(name: String)
-       do
-               file = new OFStream.open("{name}.nit")
-               write "class Root\n\tfun id: Int do return 0\nend"
-               for c in classes do
-                       write "class {c}"
-                       if c.supers.is_empty then
-                               write "\tsuper Root"
-                       else for s in c.supers do
-                               write "\tsuper {s}"
-                       end
-                       write "\tredef fun id do return {c.id}"
-                       write "end"
-               end
-               write "class L[E]\n\tsuper Root\n\tvar item:E \n\tvar next: nullable L[E]\ninit(item:E,next: nullable L[E])do\n\tself.item = item\n\tself.next=next\nend\nend"
-
-               write "fun fill: nullable L[Root]\ndo"
-               write "\tvar head: nullable L[Root] = null"
-               write "\tvar l: L[Root]"
-               for c in classes do
-                       write "\tvar l{c} = new L[{c}](new {c}, null)"
-                       write "\thead = new L[Root](l{c}, head)"
-               end
-               write "\thead = null"
-               write "for x in [0..{arraylen}[ do"
-               for i in [0..listlen[ do
-                       var c = unlist[i]
-                       write "\tvar l{i} = new L[{c}](new {c}, null)"
-                       write "\thead = new L[Root](l{i}, head)"
-               end
-               write "end"
-               write "return head"
-               write "end"
-
-               write "fun run(head1: nullable L[Root], head2: nullable L[Root]): Int\ndo"
-               write "\tvar cpt = 0"
-               write "\tvar y = {loops/list.length}"
-               write "\twhile y > 0 do"
-               write "\tvar n1 = head1"
-               write "\tvar n2 = head2"
-               write "\twhile not n1 is null do"
-               for i in [0..listlen[ do
-                       var c = list[i]
-                       write "\t\tvar l{i} = n1.item"
-                       write "\t\tvar lc{i} = l{i}.as(L[{c}])"
-                       write "\t\tvar c{i} = lc{i}.item"
-                       write "\t\tn1 = n1.next"
-                       if count then
-                               write "\t\tif c{i}.id == {c.id} then cpt += 1"
-                       end
-                       write "\t\tvar l2_{i} = n2.item"
-                       write "\t\tvar lc2_{i} = l2_{i}.as(L[{c}])"
-                       write "\t\tlc2_{i}.item = c{i}"
-                       write "\t\tn2 = n2.next"
-               end
-               write "\tend"
-               write "y -= 1"
-               write "end"
-               write "return cpt"
-               write "end"
-
-               write "var head = fill"
-               write "var loops = 25"
-               write "if not args.is_empty then loops = args.first.to_i "
-               write "for x in [0..loops[ do"
-               write "\tvar cpt = run(head, head)"
-               write "\tprint \"\{x\}:\tcpt:\{cpt\}\""
-               write "end"
-               file.close
-       end
-
-       fun writejava(name: String, interfaces: Bool)
-       do
-               var cl = ""
-               if interfaces then cl = "X"
-               file = new OFStream.open("{name}.java")
-               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} "
-                       else
-                               write "static class {c} "
-                       end
-                       if c.supers.is_empty then
-                               write "\textends Root"
-                       else for s in [c.supers.first] do
-                               write "\textends {s}"
-                       end
-                       if interfaces then
-                               write "\{\}"
-                               write "static class X{c} implements {c}"
-                       end
-                       write "\{"
-                       write "\tpublic int id() \{ return {c.id}; \}"
-                       write "\}"
-               end
-               write "static class L<E>"
-               if interfaces then
-                       write "implements Root \{"
-               else
-                       write "extends Root \{"
-               end
-               write "\tE _item; E item() \{ return _item; \} void set_item(E i) \{ _item = i; \}"
-               write "\tL<E> _next; L<E> next() \{ return _next; \} void set_next(L<E> n) \{ _next = n; \}"
-               write "\tL(E i, L<E> n) \{ set_item(i); set_next(n); \}"
-               write "\tpublic int id() \{ return -1; \}"
-               write "\}"
-
-               write "static L<Root> fill() \{"
-               write "\tL<Root> head = null;"
-               for c in classes do
-                       write "\tL<{c}> l{c} = new L<{c}>(new {cl}{c}(), null);"
-                       write "\thead = new L<Root>(l{c}, head);"
-               end
-               write "\thead = null;"
-               write "for (int x=0; x<{arraylen}; x++) \{"
-               for i in [0..listlen[ do
-                       var c = unlist[i]
-                       write "\tL<{c}> l{i} = new L<{c}>(new {cl}{c}(), null);"
-                       write "\thead = new L<Root>(l{i}, head);"
-               end
-               write "\}"
-               write "return head;"
-               write "\}"
-
-               write "static int run(L<Root> head1, L<Root> head2) \{"
-               write "\tint cpt = 0;"
-               write "\tint y = {loops/list.length};"
-               write "\twhile (y > 0) \{;"
-               write "\tL<Root> n1 = head1;"
-               write "\tL<Root> n2 = head2;"
-               write "\twhile (n1 != null) \{"
-               for i in [0..listlen[ do
-                       var c = list[i]
-                       write "\t\tRoot l{i} = n1.item();"
-                       write "\t\tL<{c}> lc{i} = (L<{c}>)l{i};"
-                       write "\t\t{c} c{i} = lc{i}.item();"
-                       write "\t\tn1 = n1.next();"
-                       if count then
-                               write "\t\tif (c{i}.id() == {c.id}) cpt += 1;"
-                       end
-                       write "\t\tRoot l2_{i} = n2.item();"
-                       write "\t\tL<{c}> lc2_{i} = (L<{c}>)l2_{i};"
-                       write "\t\tlc2_{i}.set_item(c{i});"
-                       write "\t\tn2 = n2.next();"
-               end
-               write "\t\}"
-               write "y -= 1;"
-               write "\}"
-               write "return cpt;"
-               write "\}"
-
-               write "static public void main(String args[]) \{"
-               write "L<Root> head = fill();"
-               write "int loops = 25;"
-               write "if (args.length > 0) loops = Integer.parseInt(args[0]);"
-               write "for (int x=0; x<loops; x++) \{"
-               write "\tint cpt = run(head, head);"
-               write "\tSystem.out.println(\"\" + x + \":\\t\" + cpt);"
-               write "\}"
-               write "\}"
-               write "\}"
-               file.close
-       end
-
-       fun writecsharp(name: String, interfaces: Bool)
-       do
-               var cl = ""
-               if interfaces then cl = "X"
-               file = new OFStream.open("{name}.cs")
-               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} "
-                       else
-                               write "class {c} "
-                       end
-                       if c.supers.is_empty then
-                               write "\t: Root"
-                       else for s in [c.supers.first] do
-                               write "\t: {s}"
-                       end
-                       if interfaces then
-                               write "\{\}"
-                               write "class X{c} : {c}"
-                       end
-                       write "\{"
-                       write "\tpublic int Id() \{ return {c.id}; \}"
-                       write "\}"
-               end
-               write "class L<E>"
-               if interfaces then
-                       write ": Root \{"
-               else
-                       write ": Root \{"
-               end
-               write "\tE _item;"
-               write "\tpublic E Item() \{ return _item; \}"
-               write "\tpublic void SetItem(E i) \{ _item = i; \}"
-               write "\tL<E> _next;"
-               write "\tpublic L<E> Next() \{ return _next; \}"
-               write "\tpublic void SetNext(L<E> n) \{ _next = n; \}"
-               write "\tpublic L(E i, L<E> n) \{ SetItem(i); SetNext(n); \}"
-               write "\tpublic int Id() \{ return -1; \}"
-               write "\}"
-
-               write "static L<Root> Fill() \{"
-               write "\tL<Root> head = null;"
-               for c in classes do
-                       write "\tL<{c}> l{c} = new L<{c}>(new {cl}{c}(), null);"
-                       write "\thead = new L<Root>(l{c}, head);"
-               end
-               write "\thead = null;"
-               write "for (int x=0; x<{arraylen}; x++) \{"
-               for i in [0..listlen[ do
-                       var c = unlist[i]
-                       write "\tL<{c}> l{i} = new L<{c}>(new {cl}{c}(), null);"
-                       write "\thead = new L<Root>(l{i}, head);"
-               end
-               write "\}"
-               write "return head;"
-               write "\}"
-
-               write "static int Run(L<Root> head1, L<Root> head2) \{"
-               write "\tint cpt = 0;"
-               write "\tint y = {loops/list.length};"
-               write "\twhile (y > 0) \{;"
-               write "\tL<Root> n1 = head1;"
-               write "\tL<Root> n2 = head2;"
-               write "\twhile (n1 != null) \{"
-               for i in [0..listlen[ do
-                       var c = list[i]
-                       write "\t\tRoot l{i} = n1.Item();"
-                       write "\t\tL<{c}> lc{i} = (L<{c}>)l{i};"
-                       write "\t\t{c} c{i} = lc{i}.Item();"
-                       write "\t\tn1 = n1.Next();"
-                       if count then
-                               write "\t\tif (c{i}.Id() == {c.id}) cpt += 1;"
-                       end
-                       write "\t\tRoot l2_{i} = n2.Item();"
-                       write "\t\tL<{c}> lc2_{i} = (L<{c}>)l2_{i};"
-                       write "\t\tlc2_{i}.SetItem(c{i});"
-                       write "\t\tn2 = n2.Next();"
-               end
-               write "\t\}"
-               write "y -= 1;"
-               write "\}"
-               write "return cpt;"
-               write "\}"
-
-               write "static void Main(string[] args) \{"
-               write "L<Root> head = Fill();"
-               write "int loops = 25;"
-               write "if (args.Length > 0) loops = int.Parse(args[0]);"
-               write "for (int x=0; x<loops; x++) \{"
-               write "\tint cpt = Run(head, head);"
-               write "\tSystem.Console.WriteLine(\"\" + x + \":\\t\" + cpt);"
-               write "\}"
-               write "\}"
-               write "\}"
-               file.close
-       end
-
-       fun writescala(name: String)
-       do
-               var cl = ""
-               file = new OFStream.open("{name}.scala")
-               write "object {name} \{"
-               write "class Root\n\t\{ def id: Int = 0 \}"
-               for c in classes do
-                       write "class {c} "
-                       if c.supers.is_empty then
-                               write "\textends Root"
-                       else for s in [c.supers.first] do
-                               write "\textends {s}"
-                       end
-                       write "\{"
-                       write "\toverride def id: Int = {c.id}"
-                       write "\}"
-               end
-               write "class L[E](var _item: E, var _next: L[E]) extends Root \{"
-               write "\tdef item: E = _item"
-               write "\tdef set_item(i: E) = this._item = i"
-               write "\tdef next: L[E] = _next"
-               write "\tdef set_next(n: L[E]) = this._next = n"
-               write "\toverride def id: Int = -1"
-               write "\}"
-
-               write "def fill: L[Root] = \{"
-               write "\tvar head: L[Root] = null"
-               for c in classes do
-                       write "\tvar l{c}: L[{c}] = new L[{c}](new {cl}{c}(), null)"
-                       write "\thead = new L[Root](l{c}, head)"
-               end
-               write "\thead = null"
-               write "\tfor (x <- 0 to {arraylen}) \{"
-               for i in [0..listlen[ do
-                       var c = unlist[i]
-                       write "\t\tvar l{i}: L[{c}] = new L[{c}](new {cl}{c}(), null)"
-                       write "\t\thead = new L[Root](l{i}, head)"
-               end
-               write "\t\}"
-               write "\treturn head"
-               write "\}"
-
-               write "def run(head1: L[Root], head2: L[Root]): Int = \{"
-               write "\tvar cpt: Int = 0"
-               write "\tvar y: Int = {loops/list.length}"
-               write "\twhile (y > 0) \{"
-               write "\tvar n1: L[Root] = head1"
-               write "\tvar n2: L[Root] = head2"
-               write "\twhile (n1 != null) \{"
-               for i in [0..listlen[ do
-                       var c = list[i]
-                       write "\t\tvar l{i}: Root = n1.item"
-                       write "\t\tvar lc{i}: L[{c}] = l{i}.asInstanceOf[L[{c}]]"
-                       write "\t\tvar c{i}: {c} = lc{i}.item"
-                       write "\t\tn1 = n1.next"
-                       if count then
-                               write "\t\tif (c{i}.id == {c.id}) cpt += 1"
-                       end
-                       write "\t\tvar l2_{i}: Root = n2.item"
-                       write "\t\tvar lc2_{i}: L[{c}] = l2_{i}.asInstanceOf[L[{c}]]"
-                       write "\t\tlc2_{i}.set_item(c{i})"
-                       write "\t\tn2 = n2.next"
-               end
-               write "\t\}"
-               write "y -= 1"
-               write "\}"
-               write "return cpt"
-               write "\}"
-
-               write "def main(args: Array[String]) = \{"
-               write "\tvar head: L[Root] = fill"
-               write "\tvar loops: Int = 25"
-               write "\tif (args.length > 0) \{"
-               write "\t\tloops = Integer.parseInt(args(0))"
-               write "\t\}"
-               write "\tfor (x <- 0 to loops) \{"
-               write "\t\tvar cpt: Int = run(head, head)"
-               write "\t\tprintln(\"\" + x + \":\\t\" + cpt)"
-               write "\t\}"
-               write "\}"
-               write "\}"
-               file.close
-       end
-
-       fun writecpp(name: String)
-       do
-               file = new OFStream.open("{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 "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}"
-                       end
-                       write "\{"
-                       write "\tpublic: virtual int id() \{ return {c.id}; \}"
-                       write "\};"
-               end
-               write "template<class E>"
-               write "class L: public virtual Root \{ public:"
-               write "\tE _item; virtual E item() \{ return _item; \} virtual void set_item(E i) \{ _item = i; \}"
-               write "\tL<E> *_next; virtual L<E> *next() \{ return _next; \} virtual void set_next(L<E> *n) \{ _next = n; \}"
-               write "\tL(E i, L<E> *n) \{ set_item(i); set_next(n); \}"
-               write "\};"
-
-               write "L<Root*> *fill() \{"
-               write "\tL<Root*> *head = 0;"
-               for c in classes do
-                       write "\tL<{c}*> *l{c} = new L<{c}*>(new {c}(), 0);"
-                       write "\thead = new L<Root*>(l{c}, head);"
-               end
-               write "\thead = 0;"
-               write "for (int x=0; x<{arraylen}; x++) \{"
-               for i in [0..listlen[ do
-                       var c = unlist[i]
-                       write "\tL<{c}*> *l{i} = new L<{c}*>(new {c}(), 0);"
-                       write "\thead = new L<Root*>(l{i}, head);"
-               end
-               write "\}"
-               write "return head;"
-               write "\}"
-
-               write "int run(L<Root*> *head1, L<Root*> *head2) \{"
-               write "\tint cpt = 0;"
-               write "\tint y = {loops/list.length};"
-               write "\twhile (y > 0) \{;"
-               write "\tL<Root*> *n1 = head1;"
-               write "\tL<Root*> *n2 = head2;"
-               write "\twhile (n1 != 0) \{"
-               for i in [0..listlen[ do
-                       var c = list[i]
-                       write "\t\tRoot *l{i} = n1->item();"
-                       write "\t\tL<{c}*> *lc{i} = dynamic_cast<L<{c}*>*>(l{i});"
-                       write "\t\t{c} *c{i} = lc{i}->item();"
-                       write "\t\tn1 = n1->next();"
-                       if count then
-                               write "\t\tif (c{i}->id() == {c.id}) cpt += 1;"
-                       end
-                       write "\t\tRoot *l2_{i} = n2->item();"
-                       write "\t\tL<{c}*> *lc2_{i} = dynamic_cast<L<{c}*>*>(l2_{i});"
-                       write "\t\tlc2_{i}->set_item(c{i});"
-                       write "\t\tn2 = n2->next();"
-               end
-               write "\t\}"
-               write "y -= 1;"
-               write "\}"
-               write "return cpt;"
-               write "\}"
-
-               write "int main(int argc, char **argv) \{"
-               write "L<Root*> *head = fill();"
-               write "int loops = 25;"
-               write "if (argc > 1) loops = atoi(argv[1]);"
-               write "for (int x=0; x<loops; x++) \{"
-               write "\tint cpt = run(head, head);"
-               write "\tstd::cout << x << \":\\t\" << cpt << std::endl;"
-               write "\}"
-               write "\treturn 0;"
-               write "\}"
-               file.close
-       end
-       fun writee(name: String, se: Bool)
-       do
-               var istk = ""
-               if se then istk = " is"
-
-               name.mkdir
-               file = new OFStream.open("{name}/root.e")
-               write "class ROOT"
-               write "feature id: INTEGER {istk} do Result := 0 end"
-               write "end"
-               file.close
-
-               for c in classes do
-                       file = new OFStream.open("{name}/{c}.e")
-                       write "class {c} "
-                       if c.supers.is_empty then
-                               write "\tinherit ROOT"
-                       else for s in [c.supers.first] do
-                               write "\tinherit {s}"
-                       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("{name}/l.e")
-               write "class L[E]"
-               write "inherit ROOT"
-               write "create make"
-               write "feature"
-               write "\titem: E"
-               write "\tset_item(i: E) {istk} do item := i end"
-               write "\tnext: L[E]"
-               write "\tset_next(n: L[E]) {istk} do next := n end"
-               write "\tmake(i: E; n: L[E]) {istk} do set_item(i); set_next(n); end"
-               write "end"
-               file.close
-
-               file = new OFStream.open("{name}/app{name}.e")
-               write "class APP{name.to_upper}"
-               if se then
-                       write "insert ARGUMENTS"
-               end
-               write "create make"
-               write "feature"
-               write "fill: L[ROOT] {istk}"
-               write "local"
-               write "\ti: INTEGER"
-               write "do"
-               for c in classes do
-                       write "\tcreate Result.make(create \{L[{c}]\}.make(create \{{c}\}, Void), Result)"
-               end
-               write "\tResult := Void;"
-               write "from i := 0 until i >= {arraylen} loop"
-               for i in [0..listlen[ do
-                       var c = unlist[i]
-                       write "\tcreate Result.make(create \{L[{c}]\}.make(create \{{c}\}, Void), Result)"
-               end
-               write "i := i + 1"
-               write "end"
-               write "end"
-
-               write "run(head1: L[ROOT]; head2: L[ROOT]): INTEGER{istk}"
-               write "local"
-               write "\ty: INTEGER"
-               write "\tn1, n2: L[ROOT]"
-               for i in [0..listlen[ do
-                       var c = list[i]
-                       write "\t\tl{i}: ROOT"
-                       write "\t\tlc{i}: L[{c}]"
-                       write "\t\tc{i}: {c}"
-                       write "\t\tl2_{i}: ROOT"
-                       write "\t\tlc2_{i}: L[{c}]"
-               end
-               write "do"
-               write "\tfrom y := {loops/list.length}"
-               write "\tuntil y <= 0"
-               write "\tloop"
-               write "\tfrom"
-               write "\tn1 := head1"
-               write "\tn2 := head2"
-               write "\tuntil n1 = Void loop"
-               for i in [0..listlen[ do
-                       var c = list[i]
-                       write "\t\tl{i} := n1.item"
-                       write "\t\tlc{i} ?= l{i}"
-                       write "\t\tc{i} := lc{i}.item"
-                       if count then
-                               write "\t\tif c{i}.id = {c.id} then Result := Result + 1 end"
-                       end
-                       write "\t\tl2_{i} := n2.item"
-                       write "\t\tlc2_{i} ?= l2_{i}"
-                       write "\t\tlc2_{i}.set_item(c{i})"
-                       write "\t\tn1 := n1.next"
-                       write "\t\tn2 := n2.next"
-               end
-               write "end"
-               write "y := y - 1"
-               write "end"
-               write "end"
-
-               if se then
-                       write "make{istk}"
-               else
-                       write "make(args: ARRAY[STRING]){istk}"
-               end
-               write "local"
-               write "head: L[ROOT]"
-               write "loops: INTEGER"
-               write "cpt: INTEGER"
-               write "x: INTEGER"
-               write "do"
-               write "head := fill"
-               write "loops := 25"
-               if se then
-                       write "if argument_count > 0 then loops := argument(1).to_integer"
-               else
-                       write "if args.count > 1 then loops := args.item(1).to_integer"
-               end
-               write "from x := 0 until x>=loops loop"
-               write "\tcpt := run(head, head)"
-               write "\tprint(x.out+\":%T\"+cpt.out+\"%N\")"
-               write "\t x := x + 1"
-               write "end"
-               write "end"
-               write "end"
-               write "end"
-               file.close
-       end
-
-       var count = false
-end
-
-var g = new Generator
-var name = args.first
-if args.length > 1 then
-       var opts = args[1].split_with("_")
-       for opt in opts do
-               var oname = opt.substring(0,1)
-               var val = opt.substring_from(1).to_i
-               if oname == "l" then
-                       g.listlen = val
-               else if oname == "w" then
-                       g.width = val
-               else if oname == "h" then
-                       g.height = val
-               else
-                       print "Option inconnue '{oname}'"
-                       exit(1)
-               end
-       end
-end
-g.genhier
-g.writenit(name)
-g.writejava(name, true)
-g.writecsharp(name, true)
-g.writescala(name)
-g.writecpp(name)
-g.writee("{name}_se", true)
-g.writee(name, false)