perf: reduce TreeNodeFilter allocations via IReadOnlyList and ReadOnlySpan#8238
perf: reduce TreeNodeFilter allocations via IReadOnlyList and ReadOnlySpan#8238abdelghani-moussaid wants to merge 6 commits into
Conversation
…ySpan - Widen SubExpressions to IReadOnlyList to enable optimized LINQ paths. - Implement ReadOnlySpan-based matching for .NET 8.0+ to eliminate string fragment allocations. - Use procedural loops in Span path to avoid ref-struct capture (CS9108).
Code ReviewThanks for the perf work! The intent is solid, but a few things in the implementation don't match the "zero allocations" claim, and the PR description has a couple of inaccuracies worth fixing. Detailed findings below. 🟠 Major1.
The existing string overload deliberately avoids this with an indexed for (int i = 0; i < subexprs.Count; i++)
{
if (MatchFilterPattern(subexprs[i], testNodeFragment, properties)) { ... }
}Please use the same pattern in the Span overload. As a side note, the PR description says the 2. case OperatorExpression { Op: FilterOperator.Not, SubExpressions: var subexprs }:
return !MatchFilterPattern(subexprs.Single(), testNodeFragment, properties);vs. the string overload: case OperatorExpression { Op: FilterOperator.Not, SubExpressions: [var singleSubExpr] }:
return !MatchFilterPattern(singleSubExpr, testNodeFragment, properties);Issues:
Please restore the list pattern so the two overloads match. 🟡 Moderate3. Code duplication. After fixing #1 and #2 the two overloads will be near-identical; consider either:
The second option eliminates the duplication on the TFMs where it actually matters. 4. Tests. The PR adds no tests. With both overloads shipped (string on netstandard2.0, Span on net8+), a parity regression would not be caught on one TFM. Suggest adding a small test that exercises 5. PR description nits.
✅ Looks good
Once #1 and #2 are addressed, this becomes a solid micro-optimization that genuinely lands at zero allocations across all expression shapes. |
Performance optimization for TreeNodeFilter to eliminate allocations during test discovery.
Key Changes:
Verification Results:
Unit Tests: All local TreeNodeFilter tests passed.
Related