Skip to content

Predicate benchmarks + two rounds of implementation optimization guided by dotnet-trace profiling#11

Merged
MichaConrad merged 3 commits intomainfrom
copilot/optimize-predicate-benchmarks
Feb 23, 2026
Merged

Predicate benchmarks + two rounds of implementation optimization guided by dotnet-trace profiling#11
MichaConrad merged 3 commits intomainfrom
copilot/optimize-predicate-benchmarks

Conversation

Copy link
Contributor

Copilot AI commented Feb 22, 2026

Adds a PredicatesBenchmarks class and applies two rounds of implementation-level optimizations to PredicatesAdaptive and PredicatesExact. No mathematical algorithms were changed.

Benchmarks

PredicatesBenchmarks covers all 8 method variants: Orient2d/InCircle × double/float × general-position (Stage A fast path) × near-degenerate (forces full expansion path). Uses ShortRun, MemoryDiagnoser, and EventPipeProfiler.

Round 1 — static hotspot analysis

Optimization Target
[SkipLocalsInit] on ExpansionSum, ScaleExpansionSum, PredicatesExact.InCircle, PredicatesExact.Orient2d, PredicatesAdaptive.InCircle Eliminates zero-init of large stack frames (up to 11 KB per call)
[AggressiveInlining] on TwoTwoDiff Was the only hot expansion helper missing the hint
Inline Split into MultTail and DekkersPresplit Removes two ValueTuple<double,double> allocations per TwoTwoDiff call
SIMD (Vector256<double>) in Estimate and NegateInto Vectorises summation/negation of up to 96-element spans

Round 2 — dotnet-trace profiling

Top hotspots from dotnet-trace collect (76 284 events, inclusive call-time):

Frame Samples Change
ExpansionSum 10 718 Tiered stackalloc (16/64/400 tiers); bounds-check-free merge + accumulation loops via Unsafe.Add; Unsafe.CopyBlockUnaligned for tail copies and the elen/flen=0 fast paths; [AggressiveOptimization]
ScaleExpansionSum 6 761 [SkipLocalsInit] retained; AggressiveInlining deliberately withheld — see regression note below
SpanHelpers.Memmove 93 Eliminated: was caused by Span.CopyTo in ExpansionSum fast paths
ScaleExpansion 23 [AggressiveInlining | AggressiveOptimization], [SkipLocalsInit], bounds-check-free loop
TwoTwoDiff 9 [SkipLocalsInit]
PredicatesExact.InCircle stack In-place negate eliminates bdetPos[96] + ddetPos[96] (saves 1 536 B per call); [AggressiveOptimization]
PredicatesExact.Orient2d callsite [AggressiveInlining] allows inlining into AdaptiveOrient2d Stage D

Regression caught during R2: adding [AggressiveInlining] to ScaleExpansionSum caused it to inline 3× into AdaptiveInCircle, each copy cascading into 4 inlined ScaleExpansion calls — 12 total. This bloated the JIT frame, polluted the instruction cache, and regressed Adaptive InCircle double by +52% even for Stage-A calls that never touch expansion code. Removed the hint; full recovery confirmed.

Results (N = 4 000 calls/iteration, .NET 10, AVX2)

Method Baseline After R1 After R2 Total Δ
Exact – Orient2d double (general) 986 µs 480 µs 486 µs −51%
Exact – InCircle double (near-degenerate) 7 087 µs 3 767 µs 3 810 µs −46%
Exact – InCircle double (general) 12 359 µs 7 961 µs 8 035 µs −35%
Exact – Orient2d double (near-degenerate) 294 µs 265 µs 266 µs −10%
Adaptive – Orient2d double (general) 22.1 µs 18.4 µs 18.4 µs −17%
Adaptive – InCircle double (general/hard) ~44 µs ~42 µs ~42 µs −5%
Float variants (all) ~0% (float exact uses decimal, not expansion arithmetic)

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

…ntations

Co-authored-by: MichaCo <5837539+MichaCo@users.noreply.github.com>
Copilot AI changed the title [WIP] Add benchmarking for Optimizing PredicatesAdaptive and PredicatesExact Add PredicatesBenchmarks and optimize Orient2d/InCircle implementations Feb 22, 2026
Copilot AI requested a review from MichaConrad February 22, 2026 23:23
…eExpansion, ExactInCircle

Co-authored-by: MichaCo <5837539+MichaCo@users.noreply.github.com>
Copilot AI changed the title Add PredicatesBenchmarks and optimize Orient2d/InCircle implementations Predicate benchmarks + two rounds of implementation optimization guided by dotnet-trace profiling Feb 22, 2026
@MichaConrad MichaConrad requested a review from Copilot February 23, 2026 00:22
@github-actions
Copy link

Summary

Summary
Generated on: 2/23/2026 - 12:23:35 AM
Coverage date: 2/23/2026 - 12:23:32 AM
Parser: Cobertura
Assemblies: 1
Classes: 17
Files: 7
Line coverage: 85% (1325 of 1558)
Covered lines: 1325
Uncovered lines: 233
Coverable lines: 1558
Total lines: 3859
Branch coverage: 79.1% (627 of 792)
Covered branches: 627
Total branches: 792
Method coverage: Feature is only available for sponsors
Tag: 65_22288154652

Coverage

CDT.Core - 85%
Name Line Branch
CDT.Core 85% 79.1%
CDT.Box2d`1 73.6% 100%
CDT.CdtUtils 83.1% 72.8%
CDT.CovariantReadOnlyDictionary`3 18.1% 50%
CDT.DictionaryExtensions 100% 100%
CDT.DuplicatesInfo 100%
CDT.DuplicateVertexException 66.6%
CDT.Edge 75% 66.6%
CDT.IntersectingConstraintsException 0%
CDT.KdTree`1 72.7% 65%
CDT.LayerDepth 0%
CDT.Predicates.PredicatesAdaptive 92.6% 83.3%
CDT.Predicates.PredicatesExact 35.3% 100%
CDT.TopologyVerifier 77.2% 63.8%
CDT.Triangle 66.6% 71.4%
CDT.Triangulation`1 93.8% 84.1%
CDT.TriangulationException 100%
CDT.V2d`1 44.4% 25%

@MichaConrad MichaConrad marked this pull request as ready for review February 23, 2026 00:25
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds comprehensive benchmarks for geometric predicates and applies two rounds of profiler-guided performance optimizations to the predicate implementation. The optimizations target the expensive expansion arithmetic used in exact geometric predicates, achieving significant speedups (10-51%) without changing any mathematical algorithms.

Changes:

  • Added PredicatesBenchmarks class covering all 8 predicate method variants (Orient2d/InCircle × double/float × general/near-degenerate cases)
  • Applied micro-optimizations including [SkipLocalsInit], aggressive inlining, SIMD vectorization, tiered stackalloc, and bounds-check elimination using unsafe code
  • Eliminated unnecessary temporary stack allocations in PredicatesExact.InCircle through in-place negation

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
benchmark/CDT.Benchmarks/PredicatesBenchmarks.cs Adds comprehensive benchmark suite with 16 benchmark methods covering all predicate variants, plus helper methods for generating test data
src/CDT.Core/Predicates/PredicatesExact.cs Adds optimization attributes and eliminates 1536 bytes of stack allocation per InCircle call via in-place negation
src/CDT.Core/Predicates/PredicatesAdaptive.cs Extensive optimization: SIMD vectorization in Estimate/NegateInto, tiered stackalloc in ExpansionSum, bounds-check elimination throughout, and Split function inlining

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@MichaConrad MichaConrad merged commit 732afa7 into main Feb 23, 2026
7 checks passed
@MichaConrad MichaConrad deleted the copilot/optimize-predicate-benchmarks branch February 23, 2026 00:31
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.

3 participants