#!/bin/bash [ "$DEBUG" = true ] && set -x trap 'exit 1' SIGINT mkdir -p bin build() { local file=$1 ext= dst= shift ext=${file##*.} dst=bin/${file%.*}-$ext "$@" "$dst" "$file" >/dev/null echo "$dst" } build_wasm() { local file=$1 ext= dst= shift ext=${file##*.} dst=bin/${file%.*}-$ext.wasm "$@" "$dst" "$file" >/dev/null echo wasmtime "$dst" } build_c() { build "$1" gcc -O2 -o } build_c_clang() { build "$1" clang -O2 -o } build_c_wasm() { build_wasm "$1" emcc -O2 -o } build_cpp() { build "$1" g++ -O2 -o } build_cpp_clang() { build "$1" clang++ -O2 -o } build_rs() { build "$1" rustc -O -o } build_rs_wasm() { build_wasm "$1" rustc --target wasm32-wasi -O -o } build_hs() { build "$1" ghc -O -o rm -f ${1%.*}.{o,hi} } build_go() { build "$1" go build -ldflags "-s -w" -o } build_cs_mono() { local file=$1 ext= dst= shift ext=${file##*.} dst=bin/${file%.*}-$ext mcs -out:"$dst" "$file" >/dev/null echo "mono $dst" } build_cs_dotnet() { local file=$1 ext= dst= shift ext=${file##*.} basename=${file%.*} dst=bin/${file%.*}-$ext tmppath=${TMPDIR-/tmp}/perftest_dotnetbuild/$basename mkdir -p "$tmppath" ( cd "$tmppath" dotnet new console >/dev/null ) cp "$file" "$tmppath"/Program.cs ( cd "$tmppath" dotnet publish -c Release -p:PublishSingleFile=true -p:PublishTrimmed=true --self-contained=true >/dev/null ) cp "$tmppath"/bin/Release/*/*/publish/fib "$dst" rm -rf /tmp/perftest_dotnetbuild/ echo "$dst" } unset _JAVA_OPTIONS build_java() { local file=$1 shift rm -rf build/java mkdir -p build/java javac -d build/java "$file" >/dev/null class=$(echo build/java/*) class=${class##*/} class=${class%.*} echo java -cp build/java "$class" "$@" } # $@ = cmd _time() { /bin/time -f "%e" "$@" 2>&1 >/dev/null } # $1 = N , $@ = cmd measure() { local N=$1 shift for I in $(seq 1 $N) ; do _time "$@" done | paste -sd+ | bc } # $1 = file , $2 = cmd , $@ = args run_wrap() { local file=$1 cmd=$2 shift 2 echo $cmd "$file" "$@" } # $1 = file , $2 = build fct , $@ = args build_wrap() { local file=$1 fct=$2 shift 2 dst=$("$fct" "$file") echo "$dst $@" } # $1 = N , $2 = file , $3 = fct , $@ = args test_wrap() { local N=$1 file=$2 fct=$3 shift 3 measured=$(measure "$N" $("$fct" "$file" "$@")) echo "${file#./} $EXTRA_PRINT: $measured s" } bincheck() { for I do which "$I" &>/dev/null || return $? done } # $@ = keywords skip() { stat=0 if [ -n "$ONLY" ] ; then only=1 fi for word do if [ -n "$ONLY" ] && grep -qw "$word" <<< "$ONLY"; then only=0 fi grep -qw "$word" <<< "$SKIP" && stat=$((stat+1)) done return $((stat+only)) } files="" while [ $# -gt 1 ] ; do if [ "$1" = "--" ] ; then shift break fi files="$files $1" shift done if [ -z "$files" ] ; then files=$(find -maxdepth 1 -type f | sort) fi N=10 if [ $# -gt 0 ] ; then N=$1 shift fi echo "$files" | while read -r file ; do ext=${file##*.} case $ext in c) bincheck gcc && EXTRA_PRINT="(gcc)" test_wrap "$N" "$file" build_wrap build_c "$@" bincheck clang && EXTRA_PRINT="(clang)" test_wrap "$N" "$file" build_wrap build_c_clang "$@" bincheck emcc wasmtime && EXTRA_PRINT="(wasm)" test_wrap "$N" "$file" build_wrap build_c_wasm "$@" ;; cs) bincheck mcs mono && EXTRA_PRINT="(mono)" test_wrap "$N" "$file" build_wrap build_cs_mono "$@" bincheck dotnet && EXTRA_PRINT="(dotnet)" test_wrap "$N" "$file" build_wrap build_cs_dotnet "$@" ;; cpp) bincheck g++ && EXTRA_PRINT="(g++)" test_wrap "$N" "$file" build_wrap build_cpp "$@" bincheck clang++ && EXTRA_PRINT="(clang++)" test_wrap "$N" "$file" build_wrap build_cpp_clang "$@" ;; go) bincheck go && test_wrap "$N" "$file" build_wrap build_go "$@" ;; hs) bincheck ghc && test_wrap "$N" "$file" build_wrap build_hs "$@" ;; java) bincheck javac && test_wrap "$N" "$file" build_java "$@" ;; js) bincheck node && test_wrap "$N" "$file" run_wrap "node" "$@" bincheck bun && EXTRA_PRINT="(bun)" test_wrap "$N" "$file" run_wrap "bun" "$@" ;; lua) bincheck lua && test_wrap "$N" "$file" run_wrap "lua" "$@" bincheck luajit && EXTRA_PRINT="(jit)" test_wrap "$N" "$file" run_wrap "luajit" "$@" ;; php) bincheck php && test_wrap "$N" "$file" run_wrap "php -f" "$@" ;; py) bincheck python && test_wrap "$N" "$file" run_wrap "python" "$@" bincheck pypy && EXTRA_PRINT="(pypy)" test_wrap "$N" "$file" run_wrap "pypy" "$@" ;; rb) bincheck ruby && RUBYPICK=_mri_ test_wrap "$N" "$file" run_wrap "ruby" "$@" ;; rs) bincheck rustc && test_wrap "$N" "$file" build_wrap build_rs "$@" bincheck rustc wasmtime && rustc --print target-list | grep -q '^wasm32-wasi$' && EXTRA_PRINT="(wasm)" test_wrap "$N" "$file" build_wrap build_rs_wasm "$@" ;; wasm) bincheck wasmtime && test_wrap "$N" "$file" run_wrap "wasmtime" "$@" ;; esac done