Skip to content

Instantly share code, notes, and snippets.

@radityagumay
Last active July 9, 2025 02:41
Show Gist options
  • Save radityagumay/359ef0a947ef24071a6d419858fb02e4 to your computer and use it in GitHub Desktop.
Save radityagumay/359ef0a947ef24071a6d419858fb02e4 to your computer and use it in GitHub Desktop.
android app bundle size benchmark script
#!/usr/bin/env bash
set -euo pipefail
function usage() {
echo "Usage: $0 --base=<baseline.aab> --head=<head.aab>"
exit 1
}
# ─── Parse args ─────────────────────────────────────────────────────────────────
BASE="" HEAD=""
for arg in "$@"; do
case $arg in
--base=*) BASE=${arg#*=} ;;
--head=*) HEAD=${arg#*=} ;;
*) echo "Unknown argument: $arg"; usage ;;
esac
done
[[ -z "$BASE" || -z "$HEAD" ]] && usage
[[ ! -f "$BASE" ]] && echo "✖ Base AAB not found: $BASE" && exit 1
[[ ! -f "$HEAD" ]] && echo "✖ Head AAB not found: $HEAD" && exit 1
# ─── Detect bundletool ──────────────────────────────────────────────────────────
if command -v bundletool &>/dev/null; then
BUNDLETOOL_CMD="bundletool"
elif [[ -f "${BUNDLETOOL:-bundletool.jar}" ]]; then
BUNDLETOOL_CMD="java -jar ${BUNDLETOOL:-bundletool.jar}"
else
echo "✖ bundletool not found. Install via Homebrew or drop bundletool.jar here."
exit 1
fi
if [[ $BUNDLETOOL_CMD == java* ]]; then
command -v java &>/dev/null || { echo "✖ java not on PATH"; exit 1; }
fi
# ─── Prep temp dir ──────────────────────────────────────────────────────────────
TMP=$(mktemp -d)
cleanup(){ rm -rf "$TMP"; }
trap cleanup EXIT
# ─── Collect sizes ──────────────────────────────────────────────────────────────
collect_sizes(){
local label=$1 aab=$2
# 1) per-ABI splits (default + local-testing)
local split_apks="$TMP/${label}.apks"
$BUNDLETOOL_CMD build-apks \
--bundle="$aab" \
--output="$split_apks" \
--mode=default \
--local-testing
unzip -q "$split_apks" -d "$TMP/${label}"
for abi in armeabi_v7a arm64_v8a x86_64 x86; do
# sum up any split APK containing the ABI name
local size
size=$(find "$TMP/${label}/splits" -type f -name "*${abi}*.apk" -print0 \
| xargs -0 wc -c \
| awk '{sum += $1} END{print sum+0}')
eval "${label}_${abi}=$size"
done
# 2) universal
local uni_apks="$TMP/${label}_uni.apks"
$BUNDLETOOL_CMD build-apks \
--bundle="$aab" \
--output="$uni_apks" \
--mode=universal
unzip -q "$uni_apks" -d "$TMP/${label}_uni"
local uni="$TMP/${label}_uni/universal.apk"
local size=$(wc -c <"$uni" | tr -d ' ')
eval "${label}_universal=$size"
}
collect_sizes base "$BASE"
collect_sizes head "$HEAD"
# ─── Helpers ────────────────────────────────────────────────────────────────────
to_mb3(){ echo "scale=3; $1/1024/1024" | bc; }
to_mb2(){ echo "scale=2; $1/1024/1024" | bc; }
human_diff(){
local b=$1 sign abs
if (( b < 0 )); then sign=""; abs=$(( -b )); else sign="+"; abs=$b; fi
if (( abs >= 1048576 )); then
local v=$(echo "scale=2; $abs/1048576" | bc)
echo "${sign}${v} MB"
elif (( abs >= 1024 )); then
local v=$(echo "scale=2; $abs/1024" | bc)
echo "${sign}${v} KB"
else
echo "${sign}${abs} B"
fi
}
# ─── Compute metrics ─────────────────────────────────────────────────────────────
base_uni=$(to_mb3 "$base_universal")
head_uni=$(to_mb3 "$head_universal")
diff_uni=$(human_diff $(( head_universal - base_universal )))
for abi in armeabi_v7a arm64_v8a x86_64 x86; do
eval "b=\$base_$abi"; eval "h=\$head_$abi"
eval "base_mb_$abi=\$(to_mb2 \$b)"
eval "head_mb_$abi=\$(to_mb2 \$h)"
eval "diff_mb_$abi=\$(human_diff \$(( h - b )))"
done
# ─── Print table ────────────────────────────────────────────────────────────────
printf "\n%-8s | %-16s | %-12s | %-12s | %-12s | %-12s\n" "" "Universal Apk Size" "armeabi-v7a" "arm64-v8a" "x86_64" "x86"
printf "%-8s | %-16s | %-12s | %-12s | %-12s | %-12s\n" "Target" "${base_uni} MB" "${base_mb_armeabi_v7a} MB" "${base_mb_arm64_v8a} MB" "${base_mb_x86_64} MB" "${base_mb_x86} MB"
printf "%-8s | %-16s | %-12s | %-12s | %-12s | %-12s\n" "Current" "${head_uni} MB" "${head_mb_armeabi_v7a} MB" "${head_mb_arm64_v8a} MB" "${head_mb_x86_64} MB" "${head_mb_x86} MB"
printf "%-8s | %-16s | %-12s | %-12s | %-12s | %-12s\n" "Diff" "${diff_uni}" "${diff_mb_armeabi_v7a}" "${diff_mb_arm64_v8a}" "${diff_mb_x86_64}" "${diff_mb_x86}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment