Skip to content

Commit 7ff3ecf

Browse files
committed
[string] Skip unnecessary self UTF-16 length in isEqual
For isEqual bridging comparisons, skip checking our own UTF-16 length when the string we're comparing against is known to be ASCII.
1 parent 0ca42e9 commit 7ff3ecf

File tree

2 files changed

+11
-1
lines changed

2 files changed

+11
-1
lines changed

stdlib/public/core/StringStorageBridge.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ extension _AbstractStringStorage {
9696
// Handle the case where both strings were bridged from Swift.
9797
// We can't use String.== because it doesn't match NSString semantics.
9898
let knownOther = _KnownCocoaString(other)
99+
var otherIsTagged = false
99100
switch knownOther {
100101
case .storage:
101102
return _nativeIsEqual(
@@ -105,6 +106,9 @@ extension _AbstractStringStorage {
105106
_unsafeUncheckedDowncast(other, to: __SharedStringStorage.self))
106107
#if !(arch(i386) || arch(arm))
107108
case .tagged:
109+
// Tagged means ASCII. If we're equal, our UTF-8 length is the same as our
110+
// UTF-16 length, so just compare the UTF-8 length (which is faster).
111+
otherIsTagged = true
108112
fallthrough
109113
#endif
110114
case .cocoa:
@@ -118,7 +122,11 @@ extension _AbstractStringStorage {
118122

119123
defer { _fixLifetime(other) }
120124

125+
121126
let otherUTF16Length = _stdlib_binary_CFStringGetLength(other)
127+
if otherIsTagged && self.count != otherUTF16Length {
128+
return 0
129+
}
122130

123131
// CFString will only give us ASCII bytes here, but that's fine.
124132
// We already handled non-ASCII UTF8 strings earlier since they're Swift.
@@ -131,7 +139,7 @@ extension _AbstractStringStorage {
131139
(memcmp(start, otherStart, count) == 0)) ? 1 : 0
132140
}
133141

134-
if UTF16Length != otherUTF16Length {
142+
if self.UTF16Length != otherUTF16Length {
135143
return 0
136144
}
137145

stdlib/public/core/StringUTF16View.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,8 @@ extension String.UTF16View {
531531
let idx = _utf16AlignNativeIndex(idx)
532532

533533
guard _guts._useBreadcrumbs(forEncodedOffset: idx._encodedOffset) else {
534+
// TODO: Generic _distance is still very slow. We should be able to
535+
// skip over ASCII substrings quickly
534536
return _distance(from: startIndex, to: idx)
535537
}
536538

0 commit comments

Comments
 (0)