Skip to content

Use Spans and ReadOnlyCollection.Empty in TextBlock/Line, reduce allocs#9993

Open
h3xds1nz wants to merge 14 commits intodotnet:mainfrom
h3xds1nz:minor-textblock-stuff
Open

Use Spans and ReadOnlyCollection.Empty in TextBlock/Line, reduce allocs#9993
h3xds1nz wants to merge 14 commits intodotnet:mainfrom
h3xds1nz:minor-textblock-stuff

Conversation

@h3xds1nz
Copy link
Member

@h3xds1nz h3xds1nz commented Oct 24, 2024

Description

Bringing some optimizations to TextBlock control and related components (Line; ComplexLine).

  • Empty Initialize method in TextBlock's ctor has been removed.
  • Unused private methods GetLineIndexFromDcp and ClearComplexContent have been removed (EnsureComplexContent handles the detach if its needed)
  • Instead of using new ReadOnlyCollection<T>(new List<T>(0)) numerous times, we swap to the non-allocating, generic singleton variant of ReadOnlyCollection<T>.Empty, removing all possible overhead.
  • Replaced ArrayList for InlineObjects in ComplexContent with List<InlineObject>.
  • Unused calculated variable removed in ComplexLine - double adjustedXOffset (method doesn't modify state either)
  • Unused calculated variable removed in AlignContent - Vector contentOffset (method doesn't modify state either)
  • GetRangeBounds in Line instead of using a List<Rect> now uses pre-allocated Rect[] that's wrapped in ReadOnlySpan<Rect> to its callers on return.
  • Instead of creating List<TextSegment>(1) and using Insert (that's a great combination), we use TextSegment[].
  • I've adjusted the weird loop GetTightBoundingGeometryFromTextPositions with more thoughtful impl.

new ReadOnlyCollection<T>(new List<T>(0)) vs Empty

Method Mean [ns] Error [ns] StdDev [ns] Gen0 Code Size [B] Allocated [B]
Original 6.0508 ns 0.1542 ns 0.2577 ns 0.0033 78 B 56 B
PR_EDIT 0.6467 ns 0.0061 ns 0.0051 ns - 14 B -

GetRangeBounds call old vs. new and the loop itself; without combining geometries

GetTightBoundingGeometryFromTextPositions inner loop (1 rect)

Method Mean [ns] Error [ns] StdDev [ns] Gen0 Code Size [B] Allocated [B]
Original_string 131.0 ns 1.93 ns 1.71 ns 0.0210 1,682 B 352 B
APR_EDIT_int 112.3 ns 1.14 ns 1.07 ns 0.0134 975 B 224 B

Customer Impact

Increased performance, decreased allocations.

Regression

No.

Testing

Local build, sample apps run.

Risk

Should be low, the changes are pretty much mechanical.

Microsoft Reviewers: Open in CodeFlow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Community Contribution A label for all community Contributions Included in test pass PR metadata: Label to tag PRs, to facilitate with triage Status:Completed Status:Proposed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants