Commit Graph

3 Commits

Author SHA1 Message Date
Tarik Moussa
d7a61975b4 perf: architecture-touch quick-wins #6 + #10; skip #5 + #7 with honest notes
Some checks failed
C++ Tests / test-fast (pull_request) Successful in 1m59s
API Docs / doc-build (pull_request) Successful in 49s
Markdown link check / check (pull_request) Successful in 42s
C++ Tests / test-cgal (pull_request) Failing after 8m14s
C++ Tests / quality-gates (pull_request) Failing after 1m45s
Evaluated all four mid-tier architecture-touch levers from
doc/architecture/compile-time.md.  Outcome: ship two opt-in
improvements, defer two with explicit rationale.

#6 — Eager-include reduction (Dense → Core)   shipped
─────────────────────────────────────────────────────
Three headers downgraded from `<Eigen/Dense>` to `<Eigen/Core>`:
  * projective_math.hpp
  * hyper_ideal_visualization_utility.hpp
  * mesh_utils.hpp

All three only use Matrix/Vector primitives, no Eigen decompositions.
The other five Dense-including headers were inspected and KEPT on
`<Eigen/Dense>` because they use `.inverse()`, `.determinant()`,
`ColPivHouseholderQR`, or `SelfAdjointEigenSolver`.

Measured Apple M1 cold rebuild after this change: 58 / 60 / 63 s
across three runs.  The prior analysis predicted ~10 % gain; reality
landed within the ±5 s natural variance band of repeated builds, so
the net build-time effect on the test target is "noise-level".

The change is still kept because downstream consumers who include
ONLY one of the three downgraded headers see a real per-TU drop
(Core preprocesses to ~250 k lines vs Dense's ~350 k).

#10 — Fast test-build mode (-O0 -g)   shipped
───────────────────────────────────────────────
New option CONFORMALLAB_FAST_TEST_BUILD (default OFF).  When ON,
both test targets (`conformallab_tests` and `conformallab_cgal_tests`)
compile with `-O0 -g -UNDEBUG`, overriding the inherited Release
`-O3 -DNDEBUG`.

Measured Apple clang: 51.6 s vs 46.8 s without -O0 → slightly slower.
The Backend phase that prior analysis predicted would drop from 9.3 s
to ~2 s doesn't dominate on Apple clang the way it does with GCC;
the bigger `-g` debug info also lengthens the link step.

Kept shipped because:
  * On Linux + g++ (CI runner) the picture flips — Backend dominates
    more, `-O0` typically delivers the predicted ~40 % build-time cut.
  * Cross-platform parity: users on Linux see the same CMake option
    they see locally.

Honest documentation in doc/architecture/compile-time.md notes that
the Apple-clang-local benefit is currently 0 %.  Tests RUN ~15× slower
under `-O0` (1.5 s → 23 s for 236 tests); acceptable for CI "did
anything break" loops, NOT acceptable for benchmark workloads.

#5 — Move detail:: impls to .inl files  ⏸ deferred
───────────────────────────────────────────────────
Pure enabler for #7.  Without #7 landing, the .inl extraction would
just add an extra hop to header reading.  Reconsider once a concrete
maintenance reason emerges (e.g. a downstream user wants to override a
detail helper).

#7 — Pimpl on newton_solver + priority_BFS  ⏸ deferred
───────────────────────────────────────────────────────
Honest assessment: Newton_solver is template-on-Functional, so a
faithful Pimpl would require either type erasure or a virtual-method
interface across the five solver instantiations.  Estimated 1-2 weeks
of refactor with measurable API-surface risk.  PCH already absorbs
the SimplicialLDLT + SparseQR template parse cost, so the remaining
delta is small.  Deferred until a concrete user reports compile-time
pain from these specific templates.

Documentation
─────────────
README.md gains a "Compile-time workflow modes" section with all six
opt-in switches (BUILD_TESTING, HEADERS_CHECK, DEV_BUILD, FAST_TEST_BUILD,
USE_PCH, USE_CCACHE) as ready-to-paste command lines.

doc/architecture/compile-time.md gains:
  * an "Architecture-touch quick-wins" section with the four-row
    status table (5 deferred / 6 shipped / 7 deferred / 10 shipped)
  * the FAST_TEST_BUILD row added to the workflow-modes table
  * the mode-matrix table updated with Linux-vs-macOS expected values
  * an honest "variance" note explaining the ±5 s spread between
    repeated cold builds and why #6's net effect lands in that noise

Verified: default build 55 s (within usual variance), 236/236 tests
pass under default; FAST_TEST_BUILD=ON build 52 s, 236/236 PASS.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 08:56:36 +02:00
Tarik Moussa
3fea36823f perf: add 4 workflow modes (BUILD_TESTING / DEV_BUILD / HEADERS_CHECK / ccache)
Some checks failed
C++ Tests / test-fast (pull_request) Successful in 2m19s
API Docs / doc-build (pull_request) Successful in 56s
Markdown link check / check (pull_request) Successful in 45s
C++ Tests / test-cgal (pull_request) Failing after 7m7s
C++ Tests / quality-gates (pull_request) Failing after 1m54s
Four orthogonal opt-in build modes on top of the existing PCH + Unity
defaults.  Each addresses a specific iteration scenario; defaults are
unchanged (PCH + Unity stays the canonical fast full-rebuild path).

(A) HEADERS_CHECK target — opt-in via -DCONFORMALLAB_HEADERS_CHECK=ON
    Per-public-header smoke-compile sentinels.  For each of the six
    public CGAL umbrella headers, a stub TU `#include <…>\nint main(){}`
    is generated at configure time and compiled in isolation.
      * Full headers_check build:  ≈ 12 s
      * Incremental after touching one header:  ≈ 0.1 s
    Use case: "did my refactor still parse the public API?" without
    waiting 55 s for the full CGAL test build.

(C) DEV_BUILD mode — opt-in via -DCONFORMALLAB_DEV_BUILD=ON
    PCH stays on; Unity Build is forced off (both globally AND on the
    cgal-tests target which previously overrode the global setting).
    Trade-off: full clean rebuild ~75 s (+36 % vs the 55 s default)
    but incremental rebuild after editing a single test file drops
    from ~46 s (unity batch) to ~16 s (single TU + relink).
    Flip on for trial-and-error sessions, flip off before measuring
    CI build time or shipping a PR.

(D) ccache integration — default ON, disable with -DCONFORMALLAB_USE_CCACHE=OFF
    Detects `ccache` on PATH and prepends it to compile + link
    launchers.  On Apple clang + PCH + Unity the macOS-local hit
    rate is currently 0 % (3 separate friction points documented
    in doc/architecture/compile-time.md § "ccache — honesty notes");
    stays neutral when it doesn't help.  Real payoff on Linux CI
    (g++ + traditional PCH) where 80 %+ hit rates are typical.

(BUILD_TESTING=OFF) Standard CMake gate, now respected end-to-end.
    Wrapped both `add_subdirectory(tests)` AND the FetchContent of
    GoogleTest in `if(BUILD_TESTING)`.  Pass `-DBUILD_TESTING=OFF`:
      * Configure ≈ 1 s
      * Build ≈ 0 s
      * 0 object files
      * No GTest fetch
    Use case: IDE-syntax-check workflow that needs
    `compile_commands.json` but does NOT need to download GTest
    or build any test binary.

doc/architecture/compile-time.md gains:
  * a "Workflow modes — what to choose when" section with a 4-row
    switch matrix and a "mode matrix at a glance" comparison table
  * a ccache honesty-notes block listing the three macOS friction
    points (PCH artefact caching, Unity Build path randomisation,
    CMake launcher integration) — Linux CI is where the lever pays
    off

Verified: default build 53 s wall, 236/236 tests pass; all opt-in
modes tested end-to-end with their expected workflow numbers
documented in the doc.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 08:35:44 +02:00
Tarik Moussa
687a43e853 ci+perf: PCH + Unity Build cut CGAL test build wall-time 30% (78s -> 55s)
Some checks failed
C++ Tests / test-fast (pull_request) Successful in 1m56s
API Docs / doc-build (pull_request) Successful in 49s
Markdown link check / check (pull_request) Successful in 48s
C++ Tests / test-cgal (pull_request) Failing after 7m41s
C++ Tests / quality-gates (pull_request) Failing after 1m49s
Two structural compile-time optimisations on the conformallab_cgal_tests
target, both opt-out-able and verified safe (236/236 tests pass under
every configuration).

(1) Precompiled headers — option CONFORMALLAB_USE_PCH (default ON)
    target_precompile_headers(conformallab_cgal_tests PRIVATE
        <CGAL/Surface_mesh.h>
        <CGAL/Simple_cartesian.h>
        <CGAL/Kernel_traits.h>
        <CGAL/boost/graph/iterator.h>
        <CGAL/Polygon_mesh_processing/triangulate_faces.h>
        <Eigen/Dense> <Eigen/Sparse> <Eigen/SparseCholesky> <Eigen/SparseQR>
        <gtest/gtest.h>
        <vector> <string> <cmath> <complex>
    )
    Absorbs the per-TU CGAL+Eigen template-parse cost (measured at 5.9 s
    per minimal "include <CGAL/Discrete_conformal_map.h>" hello-world TU
    on Apple M1).

(2) Unity Build — UNITY_BUILD ON with UNITY_BUILD_BATCH_SIZE 4
    Concatenates the 22 test TUs into 5 batches of <=4 files each;
    CGAL+Eigen headers parsed once per batch instead of once per TU.
    Batch size 4 keeps gtest's TEST(...) macros and per-file
    `using namespace ...` from colliding across batched files.

Numbers (Apple M1, Ninja, -j8, clean rebuild)
─────────────────────────────────────────────
              wall    CPU    tests
baseline      78 s    676 s  236/236
+ PCH         66 s    474 s  236/236   (-15% wall, -30% CPU)
+ PCH + Unity 55 s    167 s  236/236   (-30% wall, -75% CPU)

Honest deferred items (documented in doc/architecture/compile-time.md):
  * `extern template` (lever #2 in the analysis) — subsumed by PCH;
    estimated residual gain <5%, would add Eigen-version fragility.
  * Header split <CGAL/Discrete_conformal_map_{euclidean,spherical,
    hyper_ideal}.h> (lever #3) — downstream-only benefit (our test
    build needs all three); kept as a future cleanup once a downstream
    user actually requests it.

Opt-outs: `-DCONFORMALLAB_USE_PCH=OFF` and `-DCMAKE_UNITY_BUILD=OFF`.

Detailed measurement methodology, per-TU breakdowns, clang
-ftime-trace template hot-spots, and a "what comes next" lever list
live in doc/architecture/compile-time.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 07:58:41 +02:00