AttributedString Equatable conformance performance improvements #1287
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This commit includes a handful of performance improvements for
AttributedString
that provide some great speedups to itsEquatable
conformance andRuns
view. These are the changes this makes:AttributedString
attribute raw value casting: for a little while we've known that comparingAttributedString
attribute values is more expensive than we'd like. This fixes a few of those issues by:Optional
which requires looking up type metadata and allocating space for the optional. ThisOptional
in__equalAttributes
was required previously but is no longer used_AttributeValue
s that the raw value types must be the same, and when fetching a value from anAttributedString
we know that the raw values must be of the expected key type. Instead of usingas?
casts (which go through dynamic casting machinery to support bridging types) we can simply use_identityCast
to perform a much faster cast that just assumes the raw value is the type provided. I added debug-only asserts to help us quickly catch Foundation bugs where this isn't the caseI also noticed that most of the time spent in
AttributedString
's equatable conformance was inRangeSet
operations. The way we were iterating the runs view was callingRangeSet
APIs multiple times for the same information, and sinceRangeSet
isn't fully frozen/inlinable, each call requires metadata allocation and extra costs. Instead, I refactoredrangeIdx(containing:)
to provide more info to the caller and provide a public assertion message so that the callers can avoid extraRangeSet
calls that were already being made by this function.Overall, these improvements made a 30% improvement in
AttributedString
's Equatable conformance and a 45% improvement in iterating the runs view via an attribute slice: