#!/usr/bin/env bash # # Cold-start baseline: installs nothing, measures the app that is already on the device. # # ./tools/measure-startup.sh # three runs # ./tools/measure-startup.sh 5 # five runs # # Why `am start -W` rather than a benchmark library: it needs no new module and no instrumented # test APK, and "time from tap to first frame" is exactly what it reports. What it does *not* do is # measure anything inside the app — folder open, thumbnail paint and search latency need a # macrobenchmark module (see docs/PERFORMANCE.md for what is still missing and why). set -euo pipefail runs=${1:-3} package=de.softwareapp_hb.filemanager.debug component="$package/de.softwareapp_hb.filemanager.MainActivity" if ! adb shell pm list packages | grep -qx "package:$package"; then echo "measure-startup: $package is not installed." >&2 echo " ./gradlew :app:assembleDebug && adb install -r app/build/outputs/apk/debug/app-debug.apk" >&2 exit 2 fi version=$(adb shell dumpsys package "$package" | sed -n 's/.*versionName=\([^ ]*\).*/\1/p' | head -1) echo "package $package ($version), $runs cold starts" # One start that is thrown away. The first launch after an install pays for dexopt and JIT, and # folding that into a median is how a baseline gets written that nothing can meet. adb shell am force-stop "$package" sleep 1 adb shell am start -W -n "$component" >/dev/null sleep 2 times=$( for run in $(seq 1 "$runs"); do adb shell am force-stop "$package" sleep 1 adb shell am start -W -n "$component" | sed -n 's/^TotalTime: //p' | tr -d '\r' done | sort -n ) echo "runs (ms): $(echo "$times" | tr '\n' ' ')" # Median of an odd count; for an even count this takes the lower of the two middle runs, which is # the honest side to err on when the point is to notice a regression. echo "$times" | awk ' { value[NR] = $1 } END { printf "median: %d ms (min %d, max %d)\n", value[int((NR + 1) / 2)], value[1], value[NR] } '