You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
test/guess.js's unfiltered-default-pool test for VonMises ("should include VonMises in the default pool for data it fits well") currently takes ~81 seconds by itself, and is one of the single largest contributors to npm test's ~6-10 minute runtime. This was measured directly via a fresh full-suite run (10,176 tests, 627s wall clock under mocha --parallel with 3 workers on a 4-core container).
Root cause
Issue #1063 diagnosed and PR #1080 fixed a related but narrower problem: DoublyNoncentralBeta/DoublyNoncentralF.fit() chasing a near-flat likelihood ridge at unbounded Powell-search cost. #1080 bounded that single distribution's fit() search budget to ~1-2s/call — a real and correct fix, but it only bounds one candidate's cost, not guess()'s pool-wide iteration cost.
guess()'s default candidate pool has grown to ~144 distributions. For data shaped like VonMises(0, 2) (bounded, real-valued, range ≈ [-π, π]), the support hard-filter does not exclude most real-line-support distributions the way it excludes non-negative-only ones. Issue #1063's own investigation already measured several other distributions as individually slow-but-bounded on comparable data: F (8510ms), DoublyNoncentralT (4285ms), FisherZ (4251ms), QExponential (4262ms), JohnsonSU (2505ms), GeneralizedGamma (1570ms), NoncentralT (1115ms). None of these were addressed by #1080's fix, which was scoped narrowly to DoublyNoncentralBeta/F. When guess() iterates its full pool against VonMises-shaped data, calling fit() serially on every candidate that survives the support filter, these per-candidate costs (1-8s each) sum up — plus additional slowdown from CPU contention across mocha --parallel workers — to the observed ~81s for one test.
This is exactly the scenario issue #1063's own "Suggested investigation" section flagged but explicitly left out of scope for #1080:
"Consider whether ran.dist.guess()'s default candidate pool needs ... a general per-candidate timeout/cost-budget in guess()'s _fitSurvivors ... as a more robust fix than exclusion lists per distribution."
Suggested investigation
Profile guess()'s _fitSurvivors (or equivalent pool-iteration logic) against VonMises-shaped and other bounded-real-line data shapes to confirm which candidates dominate the ~81s and by how much.
Design a per-candidate cost budget or timeout inside the fit-survivor loop — e.g. capping each candidate's fit() call similarly to how Bound DoublyNoncentralBeta/F.fit() search cost #1080 capped DoublyNoncentralBeta's Powell budget, but applied generically across the pool rather than per-distribution.
Any fix must not regress guess()'s correctness/recall for genuinely well-fitting candidates — a cost budget that's too aggressive could cause guess() to silently drop a good fit.
Reproduction
constdist=require('ranjs').distconstdata=newdist.VonMises(0,2).seed(0).sample(500)constt0=Date.now()dist.guess(data)// no candidates override — real unfiltered default poolconsole.log(Date.now()-t0)// observed ~81s inside full mocha --parallel suite run
See solutions/testing/2026-07-21-1055-guess-default-pool-latent-fit-cliff.md for the original latent-cliff discovery and the test-design workaround (unfilteredPool flag in test/guess.js's FORMERLY_EXCLUDED table) that avoided asserting on the slow path for most distributions but still leaves VonMises's assertion exercising it.
Problem
test/guess.js's unfiltered-default-pool test forVonMises("should include VonMises in the default pool for data it fits well") currently takes ~81 seconds by itself, and is one of the single largest contributors tonpm test's ~6-10 minute runtime. This was measured directly via a fresh full-suite run (10,176 tests, 627s wall clock undermocha --parallelwith 3 workers on a 4-core container).Root cause
Issue #1063 diagnosed and PR #1080 fixed a related but narrower problem:
DoublyNoncentralBeta/DoublyNoncentralF.fit()chasing a near-flat likelihood ridge at unbounded Powell-search cost. #1080 bounded that single distribution'sfit()search budget to ~1-2s/call — a real and correct fix, but it only bounds one candidate's cost, notguess()'s pool-wide iteration cost.guess()'s default candidate pool has grown to ~144 distributions. For data shaped likeVonMises(0, 2)(bounded, real-valued, range ≈[-π, π]), the support hard-filter does not exclude most real-line-support distributions the way it excludes non-negative-only ones. Issue #1063's own investigation already measured several other distributions as individually slow-but-bounded on comparable data:F(8510ms),DoublyNoncentralT(4285ms),FisherZ(4251ms),QExponential(4262ms),JohnsonSU(2505ms),GeneralizedGamma(1570ms),NoncentralT(1115ms). None of these were addressed by #1080's fix, which was scoped narrowly toDoublyNoncentralBeta/F. Whenguess()iterates its full pool against VonMises-shaped data, callingfit()serially on every candidate that survives the support filter, these per-candidate costs (1-8s each) sum up — plus additional slowdown from CPU contention acrossmocha --parallelworkers — to the observed ~81s for one test.This is exactly the scenario issue #1063's own "Suggested investigation" section flagged but explicitly left out of scope for #1080:
Suggested investigation
guess()'s_fitSurvivors(or equivalent pool-iteration logic) against VonMises-shaped and other bounded-real-line data shapes to confirm which candidates dominate the ~81s and by how much.fit()call similarly to how Bound DoublyNoncentralBeta/F.fit() search cost #1080 cappedDoublyNoncentralBeta's Powell budget, but applied generically across the pool rather than per-distribution.src/dist/_guess-meta.js(mirroring the Bessel-exclusion mechanism from Explore removing the Bessel-heavy distribution exclusions from ran.dist.guess()'s default candidate pool #1051) or as a runtime cost cap insideguess()itself — the issue should weigh both, as Fix DoublyNoncentralF/Beta.fit() severe slowdown #1063 originally suggested.guess()'s correctness/recall for genuinely well-fitting candidates — a cost budget that's too aggressive could causeguess()to silently drop a good fit.Reproduction
Related
solutions/testing/2026-07-21-1055-guess-default-pool-latent-fit-cliff.mdfor the original latent-cliff discovery and the test-design workaround (unfilteredPoolflag intest/guess.js'sFORMERLY_EXCLUDEDtable) that avoided asserting on the slow path for most distributions but still leaves VonMises's assertion exercising it.