2016-02-04 22:32:08 +03:00
|
|
|
#!/bin/bash
|
2016-09-06 23:38:15 +03:00
|
|
|
set -u
|
2016-02-04 22:32:08 +03:00
|
|
|
|
|
|
|
EXPSTR='Found 664579 prime numbers.'
|
2016-09-07 17:27:38 +03:00
|
|
|
RUN_TIME="${RUN_TIME:=90}" # CPU time seconds
|
2016-09-07 21:19:55 +03:00
|
|
|
RUN_TRIES="${RUN_TRIES:=6}" # number of identical runs
|
|
|
|
MIN_NLINES="${MIN_NLINES:=10}" # it's a fatal error if we get less than this number of output lines
|
2016-09-07 17:30:13 +03:00
|
|
|
SRC_FILTER="${SRC_FILTER:=x}" # execute only given tests
|
2016-09-07 21:19:55 +03:00
|
|
|
DRY_RUN="${DRY_RUN:=0}"
|
2016-09-06 23:09:19 +03:00
|
|
|
|
2016-09-08 18:02:31 +03:00
|
|
|
export RUN_TIME
|
|
|
|
|
|
|
|
echo "# Run time limited to $RUN_TIME wall-clock seconds"
|
2016-09-06 23:09:19 +03:00
|
|
|
echo "#"
|
2016-09-08 18:02:31 +03:00
|
|
|
# Note: This increases the memory usage but should still provide linear performance.
|
2016-02-04 22:32:08 +03:00
|
|
|
|
|
|
|
function run_benchmark() {
|
|
|
|
HEADER="$1"
|
2016-09-06 23:09:19 +03:00
|
|
|
COMPILE_CMD="$2"
|
|
|
|
RUN_CMD="$3"
|
2016-02-04 22:32:08 +03:00
|
|
|
VERSION_CMD="$4"
|
|
|
|
VERSION_FILTER_CMD="$5"
|
2016-09-06 23:29:08 +03:00
|
|
|
SRC_FILE="$6"
|
2016-02-04 22:32:08 +03:00
|
|
|
|
2016-09-07 17:30:13 +03:00
|
|
|
if [ "$SRC_FILTER" != 'x' ]; then
|
|
|
|
if [ "$SRC_FILE" != "$SRC_FILTER" ]; then
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
2016-02-05 23:55:55 +03:00
|
|
|
$VERSION_CMD >/dev/null 2>&1
|
|
|
|
if [ "$?" == 127 ]; then # "command not found"
|
2016-09-06 23:09:19 +03:00
|
|
|
echo "SKIPPING: $HEADER / $VERSION_CMD" >&2
|
2016-02-05 23:40:06 +03:00
|
|
|
return # skip non-existing interpreter
|
|
|
|
fi
|
|
|
|
|
2016-09-06 23:09:19 +03:00
|
|
|
VERSION_OUT="$( $VERSION_CMD 2>&1 | $VERSION_FILTER_CMD | tr '\n' ' ' )"
|
|
|
|
|
|
|
|
echo "# $HEADER"
|
|
|
|
|
|
|
|
echo "# ... compilation"
|
|
|
|
$COMPILE_CMD || exit 1 # compilation failed
|
|
|
|
|
2016-09-07 21:19:55 +03:00
|
|
|
for n in $(seq 1 "$RUN_TRIES"); do
|
|
|
|
if [ "$DRY_RUN" -ne 0 ]; then
|
|
|
|
continue
|
|
|
|
fi
|
|
|
|
|
2016-09-06 23:09:19 +03:00
|
|
|
echo "# ... run $n"
|
2016-02-04 22:32:08 +03:00
|
|
|
|
2016-09-06 23:09:19 +03:00
|
|
|
TIMES_FILE="$(mktemp --suffix .langs_perf)" || exit 1
|
2016-02-04 22:32:08 +03:00
|
|
|
|
2016-09-06 23:09:19 +03:00
|
|
|
OUT="$(
|
|
|
|
{
|
|
|
|
/usr/bin/time -o "$TIMES_FILE" --format \
|
|
|
|
'real_TIME:%esec user_CPU:%Usec sys_CPU:%Ssec max_RSS:%Mkb swaps:%W ctx_sw:%c+%w' \
|
2016-09-08 18:02:31 +03:00
|
|
|
$RUN_CMD
|
2016-09-06 23:09:19 +03:00
|
|
|
} 2>&1
|
|
|
|
)"
|
2016-02-04 22:32:08 +03:00
|
|
|
|
2016-09-06 23:09:19 +03:00
|
|
|
TIMES_OUT="$(cat "$TIMES_FILE" | grep -vx 'Command terminated by signal 9')"
|
|
|
|
rm "$TIMES_FILE"
|
|
|
|
|
|
|
|
# check that all scripts output the same lines
|
|
|
|
if [ "$(echo "$OUT" | grep -xv "$EXPSTR")" != '' ]; then
|
|
|
|
echo "ERROR: Unexpected output: $OUT" >&2
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
NLINES="$(echo "$OUT"|wc -l)"
|
2016-09-07 21:19:55 +03:00
|
|
|
if [ "$NLINES" -lt "$MIN_NLINES" ]; then
|
2016-09-06 23:09:19 +03:00
|
|
|
echo "ERROR: Not enough successful loops: $NLINES" >&2
|
|
|
|
echo "$OUT" >&2
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2016-09-06 23:29:08 +03:00
|
|
|
echo "$TIMES_OUT nlines:$NLINES run_try:$n "\
|
|
|
|
"header:'$HEADER' version:'$VERSION_OUT' src_file:$SRC_FILE"
|
2016-09-06 23:09:19 +03:00
|
|
|
done
|
2016-02-04 22:32:08 +03:00
|
|
|
}
|
|
|
|
|
2016-09-06 23:37:49 +03:00
|
|
|
##
|
|
|
|
|
|
|
|
C='g++' ; SRC='primes.cpp' ; run_benchmark 'C++ (optimized with -O2)' \
|
|
|
|
"$C -Wall -O2 $SRC -o primes.cpp.out" './primes.cpp.out' "$C --version" 'head -n1' "$SRC"
|
2016-02-04 22:32:08 +03:00
|
|
|
rm -f ./primes.cpp.out
|
2016-09-06 23:29:08 +03:00
|
|
|
|
2016-09-06 23:37:49 +03:00
|
|
|
C='g++' ; SRC='primes.cpp' ; run_benchmark 'C++ (not optimized)' \
|
|
|
|
"$C -Wall $SRC -o primes.cpp.out" './primes.cpp.out' "$C --version" 'head -n1' "$SRC"
|
2016-02-04 22:32:08 +03:00
|
|
|
rm -f ./primes.cpp.out
|
2016-09-06 23:29:08 +03:00
|
|
|
|
2016-09-06 23:37:49 +03:00
|
|
|
##
|
|
|
|
|
|
|
|
C='go' ; SRC='primes.go' ; run_benchmark 'Go (not optimized)' \
|
|
|
|
"$C build $SRC" './primes' "$C version" 'cat' "$SRC"
|
2016-06-29 02:12:01 +03:00
|
|
|
go clean
|
2016-09-06 23:29:08 +03:00
|
|
|
|
2016-09-06 23:37:49 +03:00
|
|
|
##
|
|
|
|
|
|
|
|
C='pypy' ; SRC='primes.py' ; run_benchmark 'PyPy 2.7' 'true' "$C $SRC" "$C -V" 'cat' "$SRC"
|
|
|
|
C='python2.7' ; SRC='primes.py' ; run_benchmark 'Python 2.7' 'true' "$C $SRC" "$C -V" 'cat' "$SRC"
|
|
|
|
C='python3.2' ; SRC='primes.py' ; run_benchmark 'Python 3.2' 'true' "$C $SRC" "$C -V" 'cat' "$SRC"
|
|
|
|
C='python3.5' ; SRC='primes.py' ; run_benchmark 'Python 3.5' 'true' "$C $SRC" "$C -V" 'cat' "$SRC"
|
2016-09-07 21:19:55 +03:00
|
|
|
|
|
|
|
##
|
|
|
|
|
2016-09-06 23:37:49 +03:00
|
|
|
C='perl' ; SRC='primes.pl' ; run_benchmark 'Perl' 'true' "$C $SRC" "$C -v" 'grep built' "$SRC"
|
2016-09-07 21:19:55 +03:00
|
|
|
|
|
|
|
##
|
|
|
|
|
2016-09-06 23:37:49 +03:00
|
|
|
C='php5.6' ; SRC='primes.php' ; run_benchmark 'PHP 5.6' 'true' "$C $SRC" "$C -v" 'head -n1' "$SRC"
|
|
|
|
C='php7.0' ; SRC='primes.php' ; run_benchmark 'PHP 7.0' 'true' "$C $SRC" "$C -v" 'head -n1' "$SRC"
|
|
|
|
|
|
|
|
##
|
2016-09-06 23:29:08 +03:00
|
|
|
|
2016-09-06 23:37:49 +03:00
|
|
|
JF1='PrimeNumbersBenchmarkApp'
|
|
|
|
JF2='PrimeNumbersGenerator'
|
|
|
|
JF3='IntList'
|
2016-09-06 23:29:08 +03:00
|
|
|
|
2016-09-06 23:37:49 +03:00
|
|
|
C='javac' ; SRC='primes.java' ; run_benchmark 'Java (std)' \
|
|
|
|
"$C $SRC" "java $JF1" "$C -version" 'cat' "$SRC"
|
|
|
|
rm -f ${JF1}.class ${JF2}.class
|
|
|
|
|
|
|
|
C='javac' ; SRC='primes-alt.java' ; run_benchmark 'Java (non-std)' \
|
|
|
|
"$C $SRC" "java $JF1" "$C -version" 'cat' "$SRC"
|
|
|
|
rm -f ${JF1}.class ${JF2}.class ${JF3}.class
|
|
|
|
|
|
|
|
##
|
2016-09-06 23:29:08 +03:00
|
|
|
|
|
|
|
# Node.js has two different binary names; try both of them
|
2016-09-06 23:37:49 +03:00
|
|
|
C='node' ; SRC='primes.js' ; run_benchmark 'JavaScript (nodejs)' 'true' "$C $SRC" "$C -v" 'cat' "$SRC"
|
|
|
|
C='nodejs' ; SRC='primes.js' ; run_benchmark 'JavaScript (nodejs)' 'true' "$C $SRC" "$C -v" 'cat' "$SRC"
|
|
|
|
|
|
|
|
##
|
2016-09-06 23:29:08 +03:00
|
|
|
|
2016-09-06 23:37:49 +03:00
|
|
|
C='ruby' ; SRC='primes.rb' ; run_benchmark 'Ruby' 'true' "$C $SRC" "$C -v" 'cat' "$SRC"
|