@@ -96,6 +96,7 @@ extension _AbstractStringStorage {
96
96
// Handle the case where both strings were bridged from Swift.
97
97
// We can't use String.== because it doesn't match NSString semantics.
98
98
let knownOther = _KnownCocoaString ( other)
99
+ var otherIsTagged = false
99
100
switch knownOther {
100
101
case . storage:
101
102
return _nativeIsEqual (
@@ -105,6 +106,9 @@ extension _AbstractStringStorage {
105
106
_unsafeUncheckedDowncast ( other, to: __SharedStringStorage. self) )
106
107
#if !(arch(i386) || arch(arm))
107
108
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
108
112
fallthrough
109
113
#endif
110
114
case . cocoa:
@@ -118,7 +122,11 @@ extension _AbstractStringStorage {
118
122
119
123
defer { _fixLifetime ( other) }
120
124
125
+
121
126
let otherUTF16Length = _stdlib_binary_CFStringGetLength ( other)
127
+ if otherIsTagged && self . count != otherUTF16Length {
128
+ return 0
129
+ }
122
130
123
131
// CFString will only give us ASCII bytes here, but that's fine.
124
132
// We already handled non-ASCII UTF8 strings earlier since they're Swift.
@@ -131,7 +139,7 @@ extension _AbstractStringStorage {
131
139
( memcmp ( start, otherStart, count) == 0 ) ) ? 1 : 0
132
140
}
133
141
134
- if UTF16Length != otherUTF16Length {
142
+ if self . UTF16Length != otherUTF16Length {
135
143
return 0
136
144
}
137
145
0 commit comments