forked from famzah/langs-performance
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrun.sh
executable file
·178 lines (133 loc) · 5.32 KB
/
run.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#!/bin/bash
set -u
EXPSTR='Found 664579 prime numbers.'
RUN_TIME="${RUN_TIME:=90}" # wall-clock time seconds
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
SRC_FILTER="${SRC_FILTER:=x}" # if provided, execute only the given test
DRY_RUN="${DRY_RUN:=0}" # if enabled, do only the compilation phase
_OS="$(uname)"
if [ "$_OS" == "Linux" ]; then
TIME_CMD="$(which time)"
elif [ "$_OS" == "Darwin" ]; then
TIME_CMD="$(which gtime)"
fi
if [ "$TIME_CMD" == "" ]; then
echo "Unable to find the GNU time command." >&2
echo "If you are on a non-Linux OS such as Mac OS or *BSD you will need to install it separately." >&2
exit -1
fi
export RUN_TIME
echo "# Run time limited to $RUN_TIME wall-clock seconds"
echo "#"
# Note: This increases the memory usage but should still provide linear performance.
function run_benchmark() {
HEADER="$1"
COMPILE_CMD="$2"
RUN_CMD="$3"
VERSION_CMD="$4"
VERSION_FILTER_CMD="$5"
SRC_FILE="$6"
if [ "$SRC_FILTER" != 'x' ]; then
if [ "$SRC_FILE" != "$SRC_FILTER" ]; then
return
fi
fi
$VERSION_CMD >/dev/null 2>&1
if [ "$?" == 127 ]; then # "command not found"
echo "SKIPPING: $HEADER / $VERSION_CMD" >&2
return # skip non-existing interpreter
fi
VERSION_OUT="$( $VERSION_CMD 2>&1 | $VERSION_FILTER_CMD | tr '\n' ' ' )"
echo "# $HEADER"
echo "# ... compilation"
$COMPILE_CMD || exit 1 # compilation failed
for n in $(seq 1 "$RUN_TRIES"); do
if [ "$DRY_RUN" -ne 0 ]; then
continue
fi
echo "# ... run $n"
TIMES_FILE="$(mktemp)" || exit 1
OUT="$(
{
"$TIME_CMD" -o "$TIMES_FILE" --format \
'real_TIME:%esec user_CPU:%Usec sys_CPU:%Ssec max_RSS:%Mkb swaps:%W ctx_sw:%c+%w' \
$RUN_CMD
} 2>&1
)"
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)"
if [ "$NLINES" -lt "$MIN_NLINES" ]; then
echo "ERROR: Not enough successful loops: $NLINES" >&2
echo "$OUT" >&2
exit 1
fi
echo "$TIMES_OUT nlines:$NLINES run_try:$n "\
"header:'$HEADER' version:'$VERSION_OUT' src_file:$SRC_FILE"
done
}
##
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"
rm -f ./primes.cpp.out
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"
rm -f ./primes.cpp.out
##
C='go' ; SRC='primes.go' ; run_benchmark 'Go' \
"$C build $SRC" './primes' "$C version" 'cat' "$SRC"
go clean
##
C='swiftc' ; SRC='primes.swift' ; run_benchmark 'Swift (optimized with -O)' \
"$C $SRC -o primes.swift.out -O -swift-version 4" './primes.swift.out' "$C -version" 'head -n1' "$SRC"
rm -f ./primes.swift.out
C='swiftc' ; SRC='primes.swift' ; run_benchmark 'Swift (not optimized)' \
"$C $SRC -o primes.swift.out -swift-version 4" './primes.swift.out' "$C -version" 'head -n1' "$SRC"
rm -f ./primes.swift.out
##
C='pypy' ; SRC='primes.py' ; run_benchmark 'Python 2.7 + PyPy' '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"
C='python3.6' ; SRC='primes.py' ; run_benchmark 'Python 3.6' 'true' "$C $SRC" "$C -V" 'cat' "$SRC"
##
C='perl' ; SRC='primes.pl' ; run_benchmark 'Perl' 'true' "$C $SRC" "$C -v" 'grep built' "$SRC"
##
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"
##
JF1='PrimeNumbersBenchmarkApp'
JF2='PrimeNumbersGenerator'
JF3='IntList'
C='javac' ; SRC='primes.java' ; run_benchmark 'Java 8' \
"$C $SRC" "java $JF1" "$C -version" 'cat' "$SRC"
rm -f ${JF1}.class ${JF2}.class
C='javac' ; SRC='primes-alt.java' ; run_benchmark 'Java 8 (non-std lib)' \
"$C $SRC" "java $JF1" "$C -version" 'cat' "$SRC"
rm -f ${JF1}.class ${JF2}.class ${JF3}.class
##
# Node.js has two different binary names; try both of them
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"
##
C='ruby' ; SRC='primes.rb' ; run_benchmark 'Ruby' 'true' "$C $SRC" "$C -v" 'cat' "$SRC"
##
# -C opt-level=3 is the default opt level for the code produced by the --release target.
C='rust'; SRC='primes.rs' ; run_benchmark 'Rust' 'rustc -C opt-level=3 -o primes.rs.out primes.rs' './primes.rs.out' 'rustc -V' 'head -n1' "$SRC"
rm -f primes.rs.out
##
cd dotnet || exit 1
C='dotnet' ; SRC='primes.dotnet' ; run_benchmark 'C# .NET Core Linux' \
'util/build' 'util/run' "$C --version" 'cat' "$SRC"
rm -rf bin obj
cd .. || exit 1
##
C='ldc2' ; SRC='primes.d' ; run_benchmark 'D' \
"$C -O -of primes.d.out $SRC" './primes.d.out' "$C -version" 'head -n1' "$SRC"
rm -f ./primes.d.out