name: Compile-time perf bench # Cross-platform compile-time benchmark. Validates the predictions # made in doc/architecture/compile-time.md against the eulernest CI # runner (Linux + g++ on ARM64). # # Specifically tests whether: # 1. FAST_TEST_BUILD=ON delivers the ~40 % wall-time reduction on # Linux + g++ that was predicted from `-ftime-trace` profiling # (recall: on Apple clang + Apple M1 it was net-neutral). # 2. ccache hit rate is in the predicted 80%+ range on a warm # rerun (where the macOS-local hit rate was 0 % due to # Apple-clang + PCH friction). # # When run: # * push to main (after PR #19 lands) # * workflow_dispatch (manual trigger for ad-hoc verification) # # NOT run on every PR — this is a perf data-collection job, not a # correctness gate. Pollutes the summary with timings but does not # block merges. # ─── DISABLED auto-trigger 2026-05-26 ────────────────────────────────────── # Same precaution as `.gitea/workflows/doxygen-pages.yml`: while we work # through the pages-branch + CI-push issue surfaced during the v0.10.0 # merge, every workflow that auto-fires on main is restricted to # `workflow_dispatch` only. Manual reruns from the Gitea UI continue # to work; transient failures no longer clutter the run history. # # To re-enable: uncomment the `push:` block below. # # on: # push: # branches: # - main # paths: # - "code/CMakeLists.txt" # - "code/tests/**/CMakeLists.txt" # - "code/include/**" # - ".gitea/workflows/perf-compile-time.yml" on: workflow_dispatch: {} jobs: compile-time-matrix: runs-on: eulernest container: image: git.eulernest.eu/conformallab/ci-cpp:latest options: "--memory=2400m --memory-swap=2400m" steps: - uses: actions/checkout@v4 - name: Install ccache (idempotent) run: | which ccache >/dev/null 2>&1 || apt-get install -y --no-install-recommends ccache # ─── Run 1: baseline (PCH OFF, Unity OFF, ccache cleared) ────── - name: "Run 1: cold baseline (no PCH, no Unity, no ccache)" run: | ccache -C >/dev/null 2>&1 || true rm -rf build-baseline cmake -S code -B build-baseline -G Ninja \ -DWITH_CGAL_TESTS=ON \ -DCONFORMALLAB_USE_PCH=OFF \ -DCMAKE_UNITY_BUILD=OFF \ -DCONFORMALLAB_USE_CCACHE=OFF start=$(date +%s) nice -n 19 cmake --build build-baseline --target conformallab_cgal_tests -j1 end=$(date +%s) echo "PERF baseline_wall=$((end - start)) s" echo "PERF_BASELINE_WALL=$((end - start))" >> $GITHUB_ENV # ─── Run 2: PCH only ────────────────────────────────────────── - name: "Run 2: PCH only (Unity off, ccache off)" run: | ccache -C >/dev/null 2>&1 || true rm -rf build-pch cmake -S code -B build-pch -G Ninja \ -DWITH_CGAL_TESTS=ON \ -DCONFORMALLAB_USE_PCH=ON \ -DCMAKE_UNITY_BUILD=OFF \ -DCONFORMALLAB_USE_CCACHE=OFF start=$(date +%s) nice -n 19 cmake --build build-pch --target conformallab_cgal_tests -j1 end=$(date +%s) echo "PERF pch_only_wall=$((end - start)) s" echo "PERF_PCH_WALL=$((end - start))" >> $GITHUB_ENV # ─── Run 3: default (PCH + Unity Build + #6 Dense→Core) ─────── - name: "Run 3: default config (PCH + Unity + Dense→Core)" run: | ccache -C >/dev/null 2>&1 || true rm -rf build-default cmake -S code -B build-default -G Ninja \ -DWITH_CGAL_TESTS=ON \ -DCONFORMALLAB_USE_CCACHE=OFF start=$(date +%s) nice -n 19 cmake --build build-default --target conformallab_cgal_tests -j1 end=$(date +%s) echo "PERF default_wall=$((end - start)) s" echo "PERF_DEFAULT_WALL=$((end - start))" >> $GITHUB_ENV # ─── Run 4: + FAST_TEST_BUILD (-O0 -g) ──────────────────────── - name: "Run 4: default + FAST_TEST_BUILD=ON (-O0 -g for tests)" run: | ccache -C >/dev/null 2>&1 || true rm -rf build-fast cmake -S code -B build-fast -G Ninja \ -DWITH_CGAL_TESTS=ON \ -DCONFORMALLAB_FAST_TEST_BUILD=ON \ -DCONFORMALLAB_USE_CCACHE=OFF start=$(date +%s) nice -n 19 cmake --build build-fast --target conformallab_cgal_tests -j1 end=$(date +%s) echo "PERF fast_test_wall=$((end - start)) s" echo "PERF_FAST_WALL=$((end - start))" >> $GITHUB_ENV # ─── Run 5: ccache hit-rate validation ───────────────────────── - name: "Run 5: ccache hit-rate (rebuild build-default)" run: | ccache -C >/dev/null 2>&1 || true ccache --zero-stats >/dev/null # First rebuild: populate ccache. rm -rf build-cc cmake -S code -B build-cc -G Ninja \ -DWITH_CGAL_TESTS=ON \ -DCONFORMALLAB_USE_CCACHE=ON nice -n 19 cmake --build build-cc --target conformallab_cgal_tests -j1 >/dev/null ccache_first=$(ccache -s 2>&1 | grep -E "^\s*Hits" | head -1 | awk '{print $2}') # Second rebuild: expect cache hits. rm -rf build-cc-warm cmake -S code -B build-cc-warm -G Ninja \ -DWITH_CGAL_TESTS=ON \ -DCONFORMALLAB_USE_CCACHE=ON start=$(date +%s) nice -n 19 cmake --build build-cc-warm --target conformallab_cgal_tests -j1 end=$(date +%s) warm_wall=$((end - start)) ccache_stats=$(ccache -s 2>&1 | grep -E "Hits|Misses" | head -4) echo "── ccache stats after warm rebuild ──" echo "$ccache_stats" echo "PERF ccache_warm_wall=${warm_wall} s" echo "PERF_CCACHE_WARM_WALL=$warm_wall" >> $GITHUB_ENV # ─── Test correctness (last gate; perf data already collected) ─ - name: Verify all configs produced working binaries if: always() run: | for build in build-baseline build-pch build-default build-fast; do if [ -d "$build" ]; then ctest --test-dir "$build" -R "^cgal\." --output-on-failure --timeout 120 \ | tail -3 fi done # ─── Final summary ───────────────────────────────────────────── - name: Compile-time perf summary if: always() run: | echo "══════════════════════════════════════════════════════" echo " COMPILE-TIME PERF BENCH — Linux ARM64 / g++ / -j1" echo "══════════════════════════════════════════════════════" printf " %-30s %4s s\n" "Run 1: cold baseline" "${PERF_BASELINE_WALL:-?}" printf " %-30s %4s s\n" "Run 2: + PCH" "${PERF_PCH_WALL:-?}" printf " %-30s %4s s\n" "Run 3: + PCH + Unity (default)" "${PERF_DEFAULT_WALL:-?}" printf " %-30s %4s s\n" "Run 4: + FAST_TEST_BUILD" "${PERF_FAST_WALL:-?}" printf " %-30s %4s s\n" "Run 5: + ccache warm rerun" "${PERF_CCACHE_WARM_WALL:-?}" echo "──────────────────────────────────────────────────────" echo "Predictions to validate vs Apple-M1 baseline:" echo " ┃ FAST_TEST_BUILD: expected ~40 % faster than default" echo " ┃ ccache warm: expected ≤ 10 s (vs Apple's 55 s)" echo "──────────────────────────────────────────────────────" # Compute relative deltas if [ -n "${PERF_DEFAULT_WALL:-}" ] && [ -n "${PERF_FAST_WALL:-}" ]; then pct=$(awk -v d="${PERF_DEFAULT_WALL}" -v f="${PERF_FAST_WALL}" \ 'BEGIN { printf "%.0f", 100.0 * (d - f) / d }') echo " Δ FAST_TEST_BUILD vs default: ${pct} % wall reduction" fi if [ -n "${PERF_DEFAULT_WALL:-}" ] && [ -n "${PERF_CCACHE_WARM_WALL:-}" ]; then pct=$(awk -v d="${PERF_DEFAULT_WALL}" -v c="${PERF_CCACHE_WARM_WALL}" \ 'BEGIN { printf "%.0f", 100.0 * (d - c) / d }') echo " Δ ccache warm vs default: ${pct} % wall reduction" fi echo "══════════════════════════════════════════════════════"