Skip to content

Optimize Query.Newline + reduce query/region allocations#34

Merged
dsisco11 merged 30 commits into
masterfrom
sisco/newline-query-optimization
Jan 11, 2026
Merged

Optimize Query.Newline + reduce query/region allocations#34
dsisco11 merged 30 commits into
masterfrom
sisco/newline-query-optimization

Conversation

@dsisco11

@dsisco11 dsisco11 commented Jan 11, 2026

Copy link
Copy Markdown
Owner

Summary
This PR makes Query.Newline both semantically precise (“node occurs after a newline”) and fast by relying on green-node boundary flags instead of scanning trivia. It also removes a small set of high-impact LINQ usages from hot query paths and region resolution to reduce allocations and improve throughput.

What Changed

  • Correct + optimize newline matching:
    • Defines newline semantics as: current node has leading newline trivia OR previous sibling has trailing newline trivia.
    • Implements green matching using boundary flags only (no red-node allocation, no trivia scans).
  • Fix flag propagation semantics (token-centric ownership):
    • Boundary trivia flags are owned by tokens, not containers; containers track “contains” flags but do not claim boundary flags.
    • Adjusts propagation for lists/syntax containers to avoid incorrect boundary flag inheritance.
  • Reduce allocations in the query engine:
    • Replaces LINQ in selection modes and hottest Select(...)/combinator paths with tight loops to avoid iterator/closure allocations.
  • Speed up SyntaxEditor region resolution:
    • Refactors region traversal to keep an incremental slot/path stack and only materialize NodePath when a match is found.
  • Adds coverage + perf harness:
    • Adds unit tests for newline semantics (top-level + inside blocks) and verifies Query.NotNewline is the exact negation under the same context.
    • Adds SyntaxEditor mutation tests to ensure green flags stay correct across insert/replace/remove and undo/redo.
    • Adds a targeted BenchmarkDotNet suite for Query.Newline.

Key Files

  • Newline + query engine changes: NodeQueryTypes.cs, QueryCombinators.cs, QueryRegion.cs
  • Flag semantics + propagation: GreenNodeFlags.cs, GreenLeaf.cs, GreenList.cs, GreenSyntaxNode.cs
  • Tests: NewlineQueryTests.cs, SyntaxEditorTests.cs, GreenNodeFlagsTests.cs
  • Benchmarks: NewlineQueryBenchmarks.cs, Program.cs
  • Tracking doc: newline-query-optimization.todo

Benchmarks (NewlineQueryBenchmarks)
Using fixed settings (--warmupCount 3 --iterationCount 30 --outliers RemoveAll), current branch vs master:

  • Select(Query.Newline) - Count
    • Lines=1000: ~9.7% faster, alloc essentially unchanged
    • Lines=10000: ~5.6% faster, alloc essentially unchanged
  • Select(Query.Newline.First()) - First match
    • Lines=1000: ~13.6% faster, ~6.7% less allocated
    • Lines=10000: ~15.1% faster, ~6.7% less allocated

@dsisco11 dsisco11 merged commit bc694ba into master Jan 11, 2026
2 checks passed
@dsisco11 dsisco11 deleted the sisco/newline-query-optimization branch January 11, 2026 13:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant