From 7725873c0ed8d5ad6746d490597e6e15cf301b5f Mon Sep 17 00:00:00 2001 From: Alexandre Terrasa Date: Mon, 15 Jul 2013 14:17:45 -0400 Subject: [PATCH] benches: moved bench in its own directory at project root * 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 --- src/run_bench.sh => benchmarks/bench_engines.sh | 272 ++------- benchmarks/bench_languages.sh | 588 ++++++++++++++++++++ benchmarks/bench_plot.sh | 106 ++++ benchmarks/languages/bench_typetest_depth.nit | 394 ++++++++++++++ src/benchs/gen.nit | 666 ----------------------- 5 files changed, 1134 insertions(+), 892 deletions(-) rename src/run_bench.sh => benchmarks/bench_engines.sh (60%) create mode 100755 benchmarks/bench_languages.sh create mode 100755 benchmarks/bench_plot.sh create mode 100644 benchmarks/languages/bench_typetest_depth.nit delete mode 100644 src/benchs/gen.nit diff --git a/src/run_bench.sh b/benchmarks/bench_engines.sh similarity index 60% rename from src/run_bench.sh rename to benchmarks/bench_engines.sh index 1388d6c..3a42a04 100755 --- a/src/run_bench.sh +++ b/benchmarks/bench_engines.sh @@ -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" < 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 index 0000000..8316ab9 --- /dev/null +++ b/benchmarks/bench_languages.sh @@ -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 index 0000000..0c7d36b --- /dev/null +++ b/benchmarks/bench_plot.sh @@ -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" < " + 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 public void main(String args[]) \{" + if interfaces then + write "\t{classes.first} a = new X{classes.last}();" + write "\t{classes.first} b = new X{classes.last}();" + else + write "\t{classes.first} a = new {classes.last}();" + write "\t{classes.first} b = new X{classes.last}();" + end + write "\ttest(a, b);" + write "\}" + + write "static public void test({classes.first} a, {classes.first} 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} " + 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 "static void Main(string[] args) \{" + if interfaces then + write "\t{classes.first} a = new X{classes.last}();" + write "\t{classes.first} b = new X{classes.last}();" + else + write "\t{classes.first} a = new {classes.last}();" + write "\t{classes.first} b = new {classes.last}();" + end + write "\tTest(a, b);" + write "\}" + + write "static void Test({classes.first} a, {classes.first} 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]}) \{ 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 " + write "#include " + write "class Root\n\t\{ public: virtual int id() \{ return 0;\} \};" + for c in classes do + write "template" + 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 "void test({classes.first}* a, {classes.first}* 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]}* to = dynamic_cast<{classes[middle]}*>(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}* a = new {classes.first}();" + write "\t{classes.first}* b = new {classes.first}();" + 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 index 9dc2d32..0000000 --- a/src/benchs/gen.nit +++ /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" - 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 _next; L next() \{ return _next; \} void set_next(L n) \{ _next = n; \}" - write "\tL(E i, L n) \{ set_item(i); set_next(n); \}" - write "\tpublic int id() \{ return -1; \}" - write "\}" - - write "static L fill() \{" - write "\tL head = null;" - for c in classes do - write "\tL<{c}> l{c} = new L<{c}>(new {cl}{c}(), null);" - write "\thead = new L(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(l{i}, head);" - end - write "\}" - write "return head;" - write "\}" - - write "static int run(L head1, L head2) \{" - write "\tint cpt = 0;" - write "\tint y = {loops/list.length};" - write "\twhile (y > 0) \{;" - write "\tL n1 = head1;" - write "\tL 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 head = fill();" - write "int loops = 25;" - write "if (args.length > 0) loops = Integer.parseInt(args[0]);" - write "for (int x=0; x" - 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 _next;" - write "\tpublic L Next() \{ return _next; \}" - write "\tpublic void SetNext(L n) \{ _next = n; \}" - write "\tpublic L(E i, L n) \{ SetItem(i); SetNext(n); \}" - write "\tpublic int Id() \{ return -1; \}" - write "\}" - - write "static L Fill() \{" - write "\tL head = null;" - for c in classes do - write "\tL<{c}> l{c} = new L<{c}>(new {cl}{c}(), null);" - write "\thead = new L(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(l{i}, head);" - end - write "\}" - write "return head;" - write "\}" - - write "static int Run(L head1, L head2) \{" - write "\tint cpt = 0;" - write "\tint y = {loops/list.length};" - write "\twhile (y > 0) \{;" - write "\tL n1 = head1;" - write "\tL 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 head = Fill();" - write "int loops = 25;" - write "if (args.Length > 0) loops = int.Parse(args[0]);" - write "for (int x=0; x 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 " - write "#include " - 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" - 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 *_next; virtual L *next() \{ return _next; \} virtual void set_next(L *n) \{ _next = n; \}" - write "\tL(E i, L *n) \{ set_item(i); set_next(n); \}" - write "\};" - - write "L *fill() \{" - write "\tL *head = 0;" - for c in classes do - write "\tL<{c}*> *l{c} = new L<{c}*>(new {c}(), 0);" - write "\thead = new L(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(l{i}, head);" - end - write "\}" - write "return head;" - write "\}" - - write "int run(L *head1, L *head2) \{" - write "\tint cpt = 0;" - write "\tint y = {loops/list.length};" - write "\twhile (y > 0) \{;" - write "\tL *n1 = head1;" - write "\tL *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{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*>(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 *head = fill();" - write "int loops = 25;" - write "if (argc > 1) loops = atoi(argv[1]);" - write "for (int x=0; x= {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) -- 1.7.9.5