136 lines
4.1 KiB
Bash
136 lines
4.1 KiB
Bash
#!/usr/bin/env bash
|
|||
|
|
|
||
|
|
set -euo pipefail
|
||
|
|
|
||
|
|
command=${1:?command is required}
|
||
|
|
tool=${2:?tool is required}
|
||
|
|
|
||
|
|
case "$tool" in
|
||
|
|
maven)
|
||
|
|
dependency_cache="$HOME/.m2/repository"
|
||
|
|
wrapper_cache="$HOME/.m2/wrapper/dists"
|
||
|
|
dependency_file="benchmark/pom.xml"
|
||
|
|
wrapper_file="benchmark/.mvn/wrapper/maven-wrapper.properties"
|
||
|
|
;;
|
||
|
|
gradle)
|
||
|
|
dependency_cache="$HOME/.gradle/caches"
|
||
|
|
wrapper_cache="$HOME/.gradle/wrapper"
|
||
|
|
dependency_file="benchmark/build.gradle"
|
||
|
|
wrapper_file="benchmark/gradle/wrapper/gradle-wrapper.properties"
|
||
|
|
;;
|
||
|
|
*)
|
||
|
|
echo "Unsupported tool: $tool" >&2
|
||
|
|
exit 1
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
|
||
|
|
case "$command" in
|
||
|
|
prepare)
|
||
|
|
profile=${3:?profile is required}
|
||
|
|
mkdir -p "$(dirname "$dependency_file")" "$(dirname "$wrapper_file")"
|
||
|
|
printf '// setup-java cache benchmark v1: %s\n' "$profile" > "$dependency_file"
|
||
|
|
printf '# setup-java cache benchmark v1: %s\n' "$profile" > "$wrapper_file"
|
||
|
|
;;
|
||
|
|
reset)
|
||
|
|
rm -rf "$dependency_cache" "$wrapper_cache"
|
||
|
|
;;
|
||
|
|
populate)
|
||
|
|
profile=${3:?profile is required}
|
||
|
|
case "$profile" in
|
||
|
|
small)
|
||
|
|
dependency_megabytes=8
|
||
|
|
wrapper_megabytes=2
|
||
|
|
;;
|
||
|
|
large)
|
||
|
|
dependency_megabytes=128
|
||
|
|
wrapper_megabytes=32
|
||
|
|
;;
|
||
|
|
*)
|
||
|
|
echo "Unsupported profile: $profile" >&2
|
||
|
|
exit 1
|
||
|
|
;;
|
||
|
|
esac
|
||
|
|
mkdir -p "$dependency_cache/setup-java-benchmark"
|
||
|
|
mkdir -p "$wrapper_cache/setup-java-benchmark"
|
||
|
|
dd if=/dev/urandom \
|
||
|
|
of="$dependency_cache/setup-java-benchmark/payload" \
|
||
|
|
bs=1048576 count="$dependency_megabytes" 2>/dev/null
|
||
|
|
dd if=/dev/urandom \
|
||
|
|
of="$wrapper_cache/setup-java-benchmark/payload" \
|
||
|
|
bs=1048576 count="$wrapper_megabytes" 2>/dev/null
|
||
|
|
;;
|
||
|
|
start)
|
||
|
|
node -e "require('fs').writeFileSync('.benchmark-start', String(Date.now()))"
|
||
|
|
;;
|
||
|
|
record)
|
||
|
|
os=${3:?os is required}
|
||
|
|
profile=${4:?profile is required}
|
||
|
|
implementation=${5:?implementation is required}
|
||
|
|
iteration=${6:?iteration is required}
|
||
|
|
cache_hit=${7:?cache-hit output is required}
|
||
|
|
if [ "$cache_hit" != "true" ]; then
|
||
|
|
echo "Expected an exact dependency-cache hit for $implementation" >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
test -f "$dependency_cache/setup-java-benchmark/payload"
|
||
|
|
started=$(cat .benchmark-start)
|
||
|
|
finished=$(node -e "process.stdout.write(String(Date.now()))")
|
||
|
|
elapsed=$((finished - started))
|
||
|
|
mkdir -p .benchmark-results
|
||
|
|
printf '%s,%s,%s,%s,%s,%s\n' \
|
||
|
|
"$os" "$tool" "$profile" "$implementation" "$iteration" "$elapsed" \
|
||
|
|
>> .benchmark-results/timings.csv
|
||
|
|
;;
|
||
|
|
summarize)
|
||
|
|
summary_file=${3:?summary file is required}
|
||
|
|
results_file=".benchmark-results/timings.csv"
|
||
|
|
node --input-type=module - "$results_file" "$summary_file" <<'NODE'
|
||
|
|
import fs from 'node:fs';
|
||
|
|
|
||
|
|
const [, , resultsFile, summaryFile] = process.argv;
|
||
|
|
const rows = fs
|
||
|
|
.readFileSync(resultsFile, 'utf8')
|
||
|
|
.trim()
|
||
|
|
.split('\n')
|
||
|
|
.map(line => {
|
||
|
|
const [os, tool, profile, implementation, iteration, elapsed] =
|
||
|
|
line.split(',');
|
||
|
|
return {os, tool, profile, implementation, iteration, elapsed: +elapsed};
|
||
|
|
});
|
||
|
|
const average = implementation => {
|
||
|
|
const values = rows
|
||
|
|
.filter(row => row.implementation === implementation)
|
||
|
|
.map(row => row.elapsed);
|
||
|
|
if (values.length === 0) {
|
||
|
|
throw new Error(`No ${implementation} benchmark results were recorded`);
|
||
|
|
}
|
||
|
|
return Math.round(values.reduce((sum, value) => sum + value, 0) / values.length);
|
||
|
|
};
|
||
|
|
const baseline = average('baseline');
|
||
|
|
const candidate = average('candidate');
|
||
|
|
const change = (((candidate - baseline) / baseline) * 100).toFixed(1);
|
||
|
|
const {os, tool, profile} = rows[0];
|
||
|
|
const lines = [
|
||
|
|
`### ${tool} ${profile} cache restore on ${os}`,
|
||
|
|
'',
|
||
|
|
'| Implementation | Iteration | Wall time (ms) |',
|
||
|
|
'| --- | ---: | ---: |',
|
||
|
|
...rows.map(
|
||
|
|
row =>
|
||
|
|
`| ${row.implementation} | ${row.iteration} | ${row.elapsed} |`
|
||
|
|
),
|
||
|
|
`| **baseline average** | | **${baseline}** |`,
|
||
|
|
`| **candidate average** | | **${candidate}** |`,
|
||
|
|
'',
|
||
|
|
`Candidate change from baseline: **${change}%**`,
|
||
|
|
''
|
||
|
|
];
|
||
|
|
fs.appendFileSync(summaryFile, `${lines.join('\n')}\n`);
|
||
|
|
NODE
|
||
|
|
;;
|
||
|
|
*)
|
||
|
|
echo "Unsupported command: $command" >&2
|
||
|
|
exit 1
|
||
|
|
;;
|
||
|
|
esac
|