-
Notifications
You must be signed in to change notification settings - Fork 26
/
analyze.sh
executable file
·167 lines (138 loc) · 5.27 KB
/
analyze.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
#!/bin/bash
# Install gnuplot
sudo apt-get update && sudo apt-get install -y gnuplot
function extractMetric() {
local file="$1"
local metric="$2"
grep "$metric" "$file" | awk '{print $2}' | sed 's/ms//'
}
function average() {
echo "$@" | awk '{for(i=1;i<=NF;i++) s+=$i; print s/NF}'
}
declare -A formattedServerNames
formattedServerNames=(
["tailcall"]="Tailcall"
["gqlgen"]="Gqlgen"
["apollo"]="Apollo GraphQL"
["netflixdgs"]="Netflix DGS"
["caliban"]="Caliban"
["async_graphql"]="async-graphql"
["hasura"]="Hasura"
["graphql_jit"]="GraphQL JIT"
)
servers=("apollo" "caliban" "netflixdgs" "gqlgen" "tailcall" "async_graphql" "hasura" "graphql_jit")
resultFiles=("$@")
declare -A avgReqSecs
declare -A avgLatencies
# Extract metrics and calculate averages
for idx in "${!servers[@]}"; do
startIdx=$((idx * 3))
reqSecVals=()
latencyVals=()
for j in 0 1 2; do
fileIdx=$((startIdx + j))
reqSecVals+=($(extractMetric "${resultFiles[$fileIdx]}" "Requests/sec"))
latencyVals+=($(extractMetric "${resultFiles[$fileIdx]}" "Latency"))
done
avgReqSecs[${servers[$idx]}]=$(average "${reqSecVals[@]}")
avgLatencies[${servers[$idx]}]=$(average "${latencyVals[@]}")
done
# Generating data files for gnuplot
reqSecData="/tmp/reqSec.dat"
latencyData="/tmp/latency.dat"
echo "Server Value" >"$reqSecData"
for server in "${servers[@]}"; do
echo "$server ${avgReqSecs[$server]}" >>"$reqSecData"
done
echo "Server Value" >"$latencyData"
for server in "${servers[@]}"; do
echo "$server ${avgLatencies[$server]}" >>"$latencyData"
done
whichBench=1
if [[ $1 == bench2* ]]; then
whichBench=2
elif [[ $1 == bench3* ]]; then
whichBench=3
fi
reqSecHistogramFile="req_sec_histogram${whichBench}.png"
latencyHistogramFile="latency_histogram${whichBench}.png"
# Plotting using gnuplot
gnuplot <<-EOF
set term pngcairo size 1280,720 enhanced font "Courier,12"
set output "$reqSecHistogramFile"
set style data histograms
set style histogram cluster gap 1
set style fill solid border -1
set xtics rotate by -45
set boxwidth 0.9
set title "Requests/Sec"
stats "$reqSecData" using 2 nooutput
set yrange [0:STATS_max*1.2]
set key outside right top
plot "$reqSecData" using 2:xtic(1) title "Req/Sec"
set output "$latencyHistogramFile"
set title "Latency (in ms)"
stats "$latencyData" using 2 nooutput
set yrange [0:STATS_max*1.2]
plot "$latencyData" using 2:xtic(1) title "Latency"
EOF
# Move PNGs to assets
mkdir -p assets
mv $reqSecHistogramFile assets/
mv $latencyHistogramFile assets/
# Declare an associative array for server RPS
declare -A serverRPS
# Populate the serverRPS array
for server in "${servers[@]}"; do
serverRPS[$server]=${avgReqSecs[$server]}
done
# Get the servers sorted by RPS in descending order
IFS=$'\n' sortedServers=($(for server in "${!serverRPS[@]}"; do echo "$server ${serverRPS[$server]}"; done | sort -rn -k2 | cut -d' ' -f1))
echo "Sorted servers: ${sortedServers[@]}"
lastServer="${sortedServers[-1]}"
lastServerReqSecs=${avgReqSecs[$lastServer]}
# Start building the resultsTable
if [[ $whichBench == 1 ]]; then
resultsTable="<!-- PERFORMANCE_RESULTS_START -->\n\n| Query | Server | Requests/sec | Latency (ms) | Relative |\n|-------:|--------:|--------------:|--------------:|---------:|\n| $whichBench | \`{ posts { id userId title user { id name email }}}\` |"
elif [[ $whichBench == 2 ]]; then
resultsTable="| $whichBench | \`{ posts { title }}\` |"
elif [[ $whichBench == 3 ]]; then
resultsTable="| $whichBench | \`{ greet }\` |"
fi
# Build the resultsTable with sorted servers and formatted numbers
for server in "${sortedServers[@]}"; do
formattedReqSecs=$(printf "%.2f" ${avgReqSecs[$server]} | perl -pe 's/(?<=\d)(?=(\d{3})+(\.\d*)?$)/,/g')
formattedLatencies=$(printf "%.2f" ${avgLatencies[$server]} | perl -pe 's/(?<=\d)(?=(\d{3})+(\.\d*)?$)/,/g')
# Calculate the relative performance
relativePerformance=$(echo "${avgReqSecs[$server]} $lastServerReqSecs" | awk '{printf "%.2f", $1 / $2}')
resultsTable+="\n|| [${formattedServerNames[$server]}] | \`${formattedReqSecs}\` | \`${formattedLatencies}\` | \`${relativePerformance}x\` |"
done
if [[ $whichBench == 3 ]]; then
resultsTable+="\n\n<!-- PERFORMANCE_RESULTS_END -->"
fi
echo "resultsTable: $resultsTable"
# Print the results table in a new file
resultsFile="results.md"
echo -e $resultsTable >> $resultsFile
if [[ $whichBench == 3 ]]; then
finalResults=$(printf '%s\n' "$(cat $resultsFile)" | sed 's/$/\\n/'| tr -d '\n')
# Remove the last newline character
finalResults=${finalResults::-2}
# Print the results as a table in the terminal
echo -e $finalResults | sed "s/<!-- PERFORMANCE_RESULTS_START-->//;s/<!-- PERFORMANCE_RESULTS_END-->//"
# Check if the markers are present
if grep -q "PERFORMANCE_RESULTS_START" README.md; then
# Replace the old results with the new results
sed -i "/PERFORMANCE_RESULTS_START/,/PERFORMANCE_RESULTS_END/c\\$finalResults" README.md
else
# Append the results at the end of the README.md file
echo -e "\n$finalResults" >> README.md
fi
fi
# Move the generated images to the assets folder
mv $reqSecHistogramFile assets/
mv $latencyHistogramFile assets/
# Delete the result TXT files
for file in "${resultFiles[@]}"; do
rm "$file"
done