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
AttributedStringthat provide some great speedups to itsEquatableconformance andRunsview. These are the changes this makes:AttributedStringattribute raw value casting: for a little while we've known that comparingAttributedStringattribute values is more expensive than we'd like. This fixes a few of those issues by:Optionalwhich requires looking up type metadata and allocating space for the optional. ThisOptionalin__equalAttributeswas required previously but is no longer used_AttributeValues that the raw value types must be the same, and when fetching a value from anAttributedStringwe 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_identityCastto 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 inRangeSetoperations. The way we were iterating the runs view was callingRangeSetAPIs multiple times for the same information, and sinceRangeSetisn'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 extraRangeSetcalls 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: