Reduce noise in AttributeReadingPerformanceTests scaling assertion - #133496
Conversation
The scaling-ratio assertion in AssertLinearScaling was intermittently failing on CI (issue #131973) because SmallN=2000 produced measurements as small as ~5-23 ms. At that scale, ordinary CI jitter (GC pauses, scheduler blips, tiered-JIT recompilation) is a large fraction of the baseline, and small denominators inflate the ratio. A single ~20 ms wobble in the small run flipped a healthy 30x reading into a 41x failure against the 40x cap. Bumping SmallN from 2000 to 4000 (and LargeN from 20000 to 40000 to preserve the 10x growth ratio) roughly doubles the small-run baseline into the tens of milliseconds so jitter becomes a small percentage of the measurement rather than the whole thing. Nudging MaxRatioMultiplier from 4 to 5 adds a small extra CI headroom for any residual noise; quadratic regressions still trigger easily (prior pre-fix data measured 75-81x on 10x growth on the affected code paths). Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
🟢 Approval recommended
The change is limited to test constants (no product code impact) and the updated values remain internally consistent (preserving the 10× size ratio while adjusting the allowed scaling bound).
Pull request overview
This PR adjusts the input sizes and scaling tolerance used by AttributeReadingPerformanceTests so the linear-scaling assertion is less sensitive to wall-clock jitter in CI, while keeping the same overall “large vs small” ratio model.
Changes:
- Increase the “small” input size from 2,000 → 4,000 to move the denominator further out of the noise floor.
- Increase the “large” input size from 20,000 → 40,000 to preserve the 10×
SizeRatio. - Increase
MaxRatioMultiplierfrom 4 → 5 (raising the cap from 40× → 50×).
File summaries
| File | Description |
|---|---|
| src/libraries/System.Private.Xml/tests/Misc/AttributeReadingPerformanceTests.cs | Updates scaling-test constants (SmallN/LargeN and max ratio multiplier) to reduce intermittent failures from timing jitter. |
Review details
- Files reviewed: 1/1 changed files
- Comments generated: 0
- Review effort level: Lite
|
seems there is still some issue, I'm guessing overall timeout since I increased test run. Will take a look in a min |
- SmallN/LargeN back to 2_000/20_000 (no runtime increase vs main) - MinBaselineMs=30 floors the small-side divisor so wall-clock noise on fast readings doesn't inflate the ratio - Switch conditional from IsNotCoreClrInterpreter to IsNotInterpreter so Mono interpreter is also skipped Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
The new absolute baseline clamp (MinBaselineMs) can significantly weaken regression detection on fast machines and the PR description does not match the actual code changes (e.g., SmallN/LargeN not updated).
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 1/1 changed files
- Comments generated: 2
- Review effort level: Lite
|
seems like current failures are known. Fix slightly differs from original to reduce time we run the test for the lower bound I'm assuming some minimum time - if it's below threshold I treat it as noise. I picked 30ms. 12ms is what I treat as measurement error from personal experience this is slightly above double that. Additionally I kept slightly more relaxed multiplier. This should still detect regressions but hopefully not cause issues. |
Fixes the intermittent CI failure tracked in #131973 by making the scaling-ratio assertion in
AttributeReadingPerformanceTestsresilient to CI wall-clock jitter, without changing what regression it detects and without increasing test runtime.The flake
The test asserts
largeTime / smallTime <= 10 * MaxRatioMultiplier. A recent failure:That's about as marginal as a failure can get — a single ~1–2 ms wobble on the small run flips the result:
Same failure has been logged against four unrelated reader subclasses (
XmlReaderCreate,XmlNodeReader,XPathNavigatorReader,WrappedReader), including readers that don't even go through theXmlTextReaderImplduplicate-check path being stressed by the test (they read from a pre-parsedXmlDocument/XPathDocument). That's the fingerprint of harness noise, not a product regression.Why the lower bound is the fix
smallTimeis the denominator of the scaling ratio, so its noise dominates the assertion. WhenSmallN = 2_000:_BelowThresholdvariants (attrCount < 64) do very little parser work — measured wall time is ~5 ms locally and ~20 ms on the affected CI agent.So the correction is to lift the small-run effective denominator out of the noise floor.
Approach: baseline floor (no runtime cost)
Instead of scaling up
SmallN/LargeN(which would double or triple test wall time), this PR introduces a 30 ms baseline floor on the divisor:smallTime >= 30 ms, the assertion behaves exactly as before.smallTime < 30 ms(the noise regime), the divisor is clamped to 30, absorbing sub-30 ms jitter without letting it inflate the ratio.30 ms is deliberately just above the observed noise floor (the flaking runs measured ~20–25 ms). It's small enough that a true
O(N²)regression still blows past the 50x cap easily.Together with a slightly relaxed
MaxRatioMultiplier(4 → 5, giving a 50x cap) this eliminates the observed flake mode.Regression detection is preserved
Prior-art measurements on the pre-fix (#130968) code path — the very code these tests were written to guard — showed scaling ratios of 75–81x for 10× input growth on the long-URI variants (the actual O(N²) signature we care about). With the 30 ms floor and
SmallN = 2_000, a regression at that scale would compute aslargeTime / 30ms, i.e. still well above 50x. Detection stays intact.Sensitivity table (limit = 50x, input growth = 10x):
Other changes
IsNotCoreClrInterpreter→IsNotInterpreter— skip on the Mono interpreter too. That runner also produces highly variable timings on this workload.smallTimeand the effectivebaselineused, so a future failure clearly shows whether the floor kicked in.Change (constants + a
Math.Max)src/libraries/System.Private.Xml/tests/Misc/AttributeReadingPerformanceTests.cs:SmallN/LargeNare unchanged frommain, so total test wall time is unchanged.Fixes #131973.
Note
This pull request was drafted with the help of AI. Please review before merging.