A Spring Boot 4.1.1 order service started 12 ways (plain and extracted jar, Spring AOT output, AppCDS, AOT cache trained with and without traffic, JDK 27, native image), ten interleaved rounds each, with first-request latency; 24 cache-mismatch cases; Docker layer arithmetic. Transcripts are in output/ (no docs/ folder). Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01TF9JWFvJSNm6HVzswzZU5a
62 lines
3.5 KiB
Bash
Executable File
62 lines
3.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Startup and first-request latency for every configuration. Configurations are run in interleaved rounds
|
|
# (round 1 runs all of them once, then round 2, ...) so slow drift on a shared machine hits all of them alike.
|
|
# scripts/startup.sh [ROUNDS] default 10
|
|
source "$(dirname "$0")/lib.sh"
|
|
ROUNDS=${1:-10}
|
|
LOG="$WORK/startup-runs.txt"; : > "$LOG"
|
|
|
|
declare -A WD CMD
|
|
labels=()
|
|
add_cfg() { local l=$1 wd=$2; shift 2; labels+=("$l"); WD[$l]=$wd; CMD[$l]="$*"; }
|
|
|
|
J25=$JDK25/bin/java; J27=$JDK27/bin/java
|
|
add_cfg "1 jvm-fat-jar" "$WORK" "$J25 -jar app.jar"
|
|
add_cfg "2 jvm-extracted" "$WORK/ext" "$J25 -jar app.jar"
|
|
add_cfg "3 jvm+spring-aot" "$WORK/ext-springaot" "$J25 -Dspring.aot.enabled=true -jar app.jar"
|
|
add_cfg "4 appcds" "$WORK/ext" "$J25 -XX:SharedArchiveFile=$WORK/appcds.jsa -jar app.jar"
|
|
add_cfg "5 aot-cache fat-jar" "$WORK" "$J25 -XX:AOTCache=$WORK/fat.aot -jar app.jar"
|
|
add_cfg "6 aot-cache context-only" "$WORK/ext" "$J25 -XX:AOTCache=$WORK/refresh.aot -jar app.jar"
|
|
add_cfg "7 aot-cache traffic" "$WORK/ext" "$J25 -XX:AOTCache=$WORK/traffic.aot -jar app.jar"
|
|
add_cfg "8 aot-cache+spring-aot" "$WORK/ext-springaot" "$J25 -Dspring.aot.enabled=true -XX:AOTCache=$WORK/springaot.aot -jar app.jar"
|
|
add_cfg "9 aot-cache+spring-aot traffic" "$WORK/ext-springaot" "$J25 -Dspring.aot.enabled=true -XX:AOTCache=$WORK/springaot-traffic.aot -jar app.jar"
|
|
add_cfg "10 jdk27 plain" "$WORK/ext" "$J27 -jar app.jar"
|
|
add_cfg "11 jdk27 aot-cache" "$WORK/ext" "$J27 -XX:AOTCache=$WORK/refresh27.aot -jar app.jar"
|
|
[ -x "$WORK/aot-cache-native" ] && add_cfg "12 native image" "$WORK" "$WORK/aot-cache-native"
|
|
|
|
one_run() { # label round
|
|
local l=$1 r=$2 t0 ready started first second med50 rss
|
|
t0=$(now_ms)
|
|
start_app "${WD[$l]}" "$WORK/run.log" ${CMD[$l]} --server.port=$PORT
|
|
if ! wait_ready; then echo "RUN|$l|$r|FAILED" >> "$LOG"; stop_app; return; fi
|
|
ready=$(( $(now_ms) - t0 ))
|
|
started=$(grep -o 'Started [A-Za-z]* in [0-9.]* seconds' "$WORK/run.log" | awk '{print $4*1000}')
|
|
first=$(post_order); second=$(get_order)
|
|
med50=$(for i in $(seq 1 50); do post_order; echo; done | grep . | median)
|
|
rss=$(rss_mb)
|
|
echo "RUN|$l|$r|ready=$ready|started=${started:-n/a}|first=$first|second=$second|next50=$med50|rss=$rss" >> "$LOG"
|
|
stop_app; sleep 0.5
|
|
}
|
|
|
|
echo "# ${#labels[@]} configurations x $ROUNDS rounds; one unrecorded warm-up round first (so cache files are in the page cache)"
|
|
for l in "${labels[@]}"; do one_run "$l" 0; done; : > "$LOG"
|
|
for r in $(seq 1 $ROUNDS); do
|
|
for l in "${labels[@]}"; do one_run "$l" "$r"; done
|
|
echo "round $r done" >&2
|
|
done
|
|
|
|
field() { grep -F "RUN|$1|" "$LOG" | grep -o "$2=[0-9.]*" | cut -d= -f2; }
|
|
echo
|
|
echo "== medians of $ROUNDS runs (min..max in brackets), milliseconds; rss in MB"
|
|
printf '%-32s %-20s %-20s %-20s %-18s %s\n' "configuration" "ready (exec->200)" "Boot 'Started in'" "1st POST /orders" "next 50 (median)" "RSS"
|
|
for l in "${labels[@]}"; do
|
|
f=$(grep -cF "RUN|$l|" "$LOG"); ok=$(grep -F "RUN|$l|" "$LOG" | grep -vc FAILED)
|
|
cell() { local v; v=$(field "$l" "$1"); printf '%-20s ' "$(echo "$v" | median) [$(echo "$v" | minmax)]"; }
|
|
printf '%-32s ' "$l"; cell ready; cell started; cell first; printf '%-18s ' "$(field "$l" next50 | median)"; printf '%s' "$(field "$l" rss | median)"
|
|
[ "$ok" != "$f" ] && printf ' (%s of %s runs failed)' $((f-ok)) $f
|
|
echo
|
|
done
|
|
echo
|
|
echo "== every run"
|
|
sed 's/^RUN|//; s/|/ /g' "$LOG"
|