bench: FE-absorption benchmark lane with BEFORE baselines + pyfixest yardstick (scenarios 7-13)#600
Conversation
…est yardstick Seven realistic workloads (scenarios 7-13 in docs/performance-scenarios.md) timing the MAP-demeaning hot path (demean_by_groups / within_transform): county policy event study, firm panel with churn, scanner store-week, 5M-order geo experiment, survey BRR replicates, correlated-FE stress, and a small-panel guard. Subprocess-isolated multi-run protocol with CV reporting (all committed baselines at CV 0.3-8.6%), ATT/SE identity capture with a --check-estimates gate (validated pass and fail directions), and an optional pyfixest yardstick lane guarded on import (coefficient parity < 1e-6 on the exact-estimand scenarios; 6e-13 to 2.7e-9 measured). Measurement-only: no library behavior change, no new package dependencies; benchmarks are not pytest-collected (verified). The committed BEFORE baseline records the tail_stress non-convergence warning as evidence of the max_iter=100 contract issue the follow-up optimization PR addresses. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Overall Assessment✅ Looks good. The PR is measurement-only and does not change estimator math, variance, weighting, assumptions, or defaults. I found no unmitigated P0/P1 methodology or inference issues. Executive Summary
MethodologyNo blocking findings. Affected methods: P3 informational: Code QualityNo findings. The benchmark code is isolated, deterministic by seeded DGPs, and does not introduce public API surface. PerformanceFinding 1 Finding 2 MaintainabilityNo findings. The added benchmark files are separated from runtime library code and share DGP construction through Tech DebtNo blocking findings. Existing FE-absorption optimization work is already documented as performance work; this PR adds measurement surface rather than new estimator debt. SecurityNo findings. I did not find secrets, credentials, or unsafe subprocess handling in the changed benchmark files. Documentation/TestsFinding 3 |
…add repeats guard - gen_findings_tables.py cell() now derives the noisy flag from fit_cv > 10% for records without a precomputed `noisy` field (pyfixest lane), and marks timing-only yardstick cells (coef=None) as `proxy`; rendered footnote explains both qualifiers. Regenerated the fe_absorption table: firm_churn pyfixest now reads (cv 20.3%, noisy, proxy), scanner_twfe (cv 12.3%, noisy). - bench_fe_absorption_pyfixest.py: add the same --repeats >= 1 argparse guard as the main lane (verified: --repeats 0 now exits 2 with a clear error). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment✅ Looks good. This re-review found no unmitigated P0/P1 issues. Executive Summary
MethodologyNo blocking findings. The benchmark invocations match the relevant registry contracts: TWFE within-transform/FWL at P3 informational: Code QualityNo findings. The benchmark code is isolated under PerformanceNo findings. Prior finding resolved: MaintainabilityNo findings. Shared DGP construction is factored into Tech DebtNo blocking findings. The benchmark documents the existing MAP iteration-cap issue rather than adding estimator debt. SecurityNo findings. The subprocess benchmark calls use argument vectors, not shell interpolation, in Documentation/TestsNo findings. Prior findings resolved: the generated performance table now surfaces both |
Summary
benchmarks/speed_review/bench_fe_absorption.py, scenarios 7-13 indocs/performance-scenarios.md): seven realistic workloads timing the MAP-demeaning hot path (demean_by_groups/within_transform) - county policy event study (SunAbraham, 3,109 counties x 60 months), firm panel with entry/exit churn (SunAbraham, 2.4M rows), scanner store-week (TWFE, 3.3M rows), 5M-order geo experiment (DiDabsorb=), survey BRR replicates (DiD absorb + 80 replicate re-demeans), correlated-FE stress, and a small-panel regression guard.baselines/fe_absorption_before.json) are at CV 0.3-8.6%.--check-estimatesgate so the follow-up optimization PR can prove estimates are unchanged (unified tolerances recorded in the JSON; gate validated in both pass and fail directions, exit 0/1).bench_fe_absorption_pyfixest.py), guarded onimport pyfixest(exits 0 with a message when absent - never a dependency). Asserts coefficient parity < 1e-6 vs the diff-diff baseline on the four exact-estimand scenarios (measured 6e-13 to 2.7e-9); Sun-Abraham scenarios are timing-only via the saturatedi(rel_time)regression (pyfixest 0.60 has nosunab()); the survey scenario is skipped (no BRR path in pyfixest).docs/performance-scenarios.mdwith the scenario definitions + provenance; adds a findings section todocs/performance-plan.mdwith an auto-generated results table (fe_absorptionmarker pair registered ingen_findings_tables.py); README + CHANGELOG entries.tail_stressnon-convergence warning (demean_by_groups ... did not converge in 100 iterations) as evidence of themax_iter=100contract issue the follow-up PR addresses.Methodology references (required if estimator / math changes)
diff_diff/source files touched)Validation
testpaths=["tests"]verified, 8,240 tests still collect cleanly)Security / privacy
Generated with Claude Code