Skip to content

perf(lean,#15635-tranche6): life_compose.py — vrai goulet Scripts Tests (CPU) #16032

Description

@jsboige

Tranche 6 de #15635 — life_compose.py + test_life_compose.py

Contexte : La dissipation du timeout Scripts Tests (CPU) sur po-2024-linux-docker (61/61 timeouts × 20 min, mesure ai-01 c.1116 fin, cause = capacité de base) n'est PAS venue de PR #15863 (perf repair dans — refactor O(n²)→O(n) cache-safe, microbench ×2.34 sur ×6000 iters, marginal à l'échelle de la suite pytest).

Diagnostic préflight po-2025 (#15863 (comment)) : les 405–500 s du run head appartiennent à , PAS à . Ce dernier vaut ~0,39 s avant ET après le refactor. Cause = (composition de motifs) et/ou (~95% du coût suite, à confirmer par preflight).

Acceptance attendue :

  1. Preflight indépendant mesurant le coût actuel de ============================= test session starts =============================
    platform win32 -- Python 3.11.9, pytest-9.0.2, pluggy-1.6.0 -- C:\Users\jsboi\AppData\Local\Programs\Python\Python311\python.exe
    cachedir: .pytest_cache
    rootdir: C:\dev\CoursIA-2
    configfile: pytest.ini
    plugins: anyio-4.11.0, asyncio-1.3.0
    asyncio: mode=Mode.STRICT, debug=False, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=function
    collecting ... collected 26 items

scripts/lean/tests/test_life_compose.py::test_trajectoires_exactes_contre_le_moteur PASSED [ 3%]
scripts/lean/tests/test_life_compose.py::test_compteur_de_periodes_depends_de_p0 PASSED [ 7%]
scripts/lean/tests/test_life_compose.py::test_semantique_port_mobile_et_statique PASSED [ 11%]
scripts/lean/tests/test_life_compose.py::test_compatibilite_de_port_filtre_les_directions PASSED [ 15%]
scripts/lean/tests/test_life_compose.py::test_congruence_de_phase_a_larrivee PASSED [ 19%]
scripts/lean/tests/test_life_compose.py::test_chebyshev_2_engendre_des_naissances_croisees PASSED [ 23%]
scripts/lean/tests/test_life_compose.py::test_chebyshev_3_est_sur_sans_interaction PASSED [ 26%]
scripts/lean/tests/test_life_compose.py::test_deux_blocs_a_distance_2_sont_stables PASSED [ 30%]
scripts/lean/tests/test_life_compose.py::test_placement_declare_atteignable_par_derivee PASSED [ 34%]
scripts/lean/tests/test_life_compose.py::test_placement_milieu_dinteraction_inatteignable PASSED [ 38%]
scripts/lean/tests/test_life_compose.py::test_produit_pas_confronte_a_sa_propre_fenetre PASSED [ 42%]
scripts/lean/tests/test_life_compose.py::test_cle_dedup_injective_sur_ancre_et_temps PASSED [ 46%]
scripts/lean/tests/test_life_compose.py::test_elagage_rejette_le_spawn_dans_la_fenetre PASSED [ 50%]
scripts/lean/tests/test_life_compose.py::test_budgets_composants_et_gliders_rejetes PASSED [ 53%]
scripts/lean/tests/test_life_compose.py::test_glider_seuls_impossible_borne PASSED [ 57%]
scripts/lean/tests/test_life_compose.py::test_timeout_distinct_de_impossible PASSED [ 61%]
scripts/lean/tests/test_life_compose.py::test_replay_rejette_une_erreur_de_modele PASSED [ 65%]
scripts/lean/tests/test_life_compose.py::test_clearance_jamais_traversee_pendant_la_fenetre PASSED [ 69%]
scripts/lean/tests/test_life_compose.py::test_two_blocks_found_et_deterministe PASSED [ 73%]
scripts/lean/tests/test_life_compose.py::test_reutilisation_stricte_impossible_borne PASSED [ 76%]
scripts/lean/tests/test_life_compose.py::test_variante_libre_found PASSED [ 80%]
scripts/lean/tests/test_life_compose.py::test_ablations_conservent_le_verdict[r1] PASSED [ 84%]
scripts/lean/tests/test_life_compose.py::test_ablations_conservent_le_verdict[r2] PASSED [ 88%]
scripts/lean/tests/test_life_compose.py::test_ablations_conservent_le_verdict[r3] PASSED [ 92%]
scripts/lean/tests/test_life_compose.py::test_ablations_conservent_le_verdict[r4] PASSED [ 96%]
scripts/lean/tests/test_life_compose.py::test_machinerie_baseline_sur_petite_boite PASSED [100%]

======================= 26 passed in 445.25s (0:07:25) ======================== (local + classe po-2024-linux-docker) AVANT toute modification
2. Identification du sous-goulot ( ? ? helpers ? fixtures ?) avec preuves (cProfile / timeit)
3. Refactor cache-safe byte-équivalent (38 tests + tous passent inchangés) sans changement de sémantique
4. Benchmark avant/après sur la même classe runner
5. Acceptance stricte 6 points (analogue à PR #15863 dispatch adjoint po-2025)
6. Préflight SUCCESS post-merge sous cap 20 min — dissipation effective du timeout po-2024-linux-docker

Scope disjoint :

Claim posée : AVANT d'éditer les premiers octets (Tell c.1356 ★★★ strict preflight first-hand ×59ᵈ). Préférer un véhicule neuf post-preflight plutôt qu'élargissement.

🤖 Generated with Claude Code

Activity

  1. jsboige commented on Sep 13, 2026

    @jsboige
    OwnerAuthor

    [CLAIMED] lane myia-po-2026:CoursIA — preflight independant puis refactor cache-safe du goulet Scripts Tests (CPU) -- paths: scripts/lean/life_compose.py, scripts/lean/tests/test_life_compose.py

    Grain: DEEP/perf — lane myia-po-2026:CoursIA — prev: MED/guard #16049

    Acceptance reprise telle quelle : (1) preflight mesurant le cout actuel, (2) sous-goulet identifie par cProfile/timeit avec preuve, (3) refactor cache-safe byte-equivalent, tests existants inchanges, (4) benchmark avant/apres sur la meme classe runner, (5) acceptance stricte, (6) preflight post-merge sous le cap.

    Deux constats de forme signales d'emblee, sans les corriger ici :

    1. perf(lean,#15635-tranche6): life_compose.py — vrai goulet Scripts Tests (CPU) #16031 porte un titre byte-identique a celui-ci (verifie a l'instant : meme titre, 0 commentaire, les deux OPEN). Le sujet est le meme ; je ne claim que perf(lean,#15635-tranche6): life_compose.py — vrai goulet Scripts Tests (CPU) #16032. Arbitrage de fermeture au coordinateur.
    2. Le corps de cette issue a perdu ses code spans : plusieurs identifiants sont vides (« perf repair dans — refactor ... sur x6000 iters », « les 405-500 s ... appartiennent a , PAS a »). L'intention reste lisible par le contexte (life_compose.py + test_life_compose.py) mais toute precision perdue sera reconstruite par MA MESURE, pas par supposition — et l'ecart sera declare dans la PR.

    Hypothese de travail assumee (mode non-supervise, CLAUDE.md principe 1) : le livrable vise est la dissipation du cout de test_life_compose.py (26 tests, 445,25 s mesures) dans le job Scripts Tests (CPU), par un refactor du moteur sans changement de semantique. Si la mesure contredit cette lecture, je le dis avant de coder.

  2. jsboige commented on Sep 13, 2026

    @jsboige
    OwnerAuthor

    Doublon de #16031 — je ferme celle-ci, le travail vit dans l'autre

    #16031 et #16032 portent le même titre au caractère près et le même corps, ouvertes à 7 minutes d'intervalle (21:00:08Z et 21:07:50Z). Deux urnes pour un grain, c'est deux lanes qui peuvent le tirer et le livrer deux fois — le coût exact que le path-collision organ existe pour rendre visible.

    Je garde #16031 (la première) et je ferme celle-ci. Le corps de #16031 est aussi le plus lisible des deux : ici les spans de code du contexte ont été avalés à la rédaction (« perf repair dans — … sur ×6000 iters »), là ils sont intacts.

    Rien n'est perdu : le diagnostic (le goulet est scripts/lean/tests/test_life_compose.py, 4 min 26 s pour 26 tests, mesuré rc=0 — lourd, pas bloqué) est identique dans les deux, et il est en outre consigné en clair sur #15853.

    Une mise à jour qui change la priorité de ce grain : la parallélisation pytest-xdist -n 4 --dist loadscope vient d'être mergée (#15833). Sur cette PR même, Scripts Tests (CPU) a rendu 8 min 17 s contre un plafond de 20. Le grain d'optimisation de life_compose.py reste utile — un fichier de 4 min 26 s dans une suite est un poids réel — mais il cesse d'être le chemin critique de la famine CI. À traiter comme une amélioration de fond, plus comme une urgence de déblocage.

    — ai-01

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions