Skip to content

Commit ec35728

Browse files
committed
[stdlib] String.UTF16View: Rework thresholds for relative indexing
We commonly start from the `startIndex`, in which case `_nativeGetOffset` is essentially free. Consider this case when calculating the threshold for using breadcrumbs.
1 parent 6fee1b3 commit ec35728

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

stdlib/public/core/StringUTF16View.swift

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ extension String.UTF16View: BidirectionalCollection {
138138
@inlinable @inline(__always)
139139
public var endIndex: Index { return _guts.endIndex }
140140

141+
@inline(__always)
142+
internal var _breadcrumbStride: Int { _StringBreadcrumbs.breadcrumbStride }
143+
141144
@inlinable @inline(__always)
142145
public func index(after idx: Index) -> Index {
143146
var idx = _guts.ensureMatchingEncoding(idx)
@@ -201,7 +204,9 @@ extension String.UTF16View: BidirectionalCollection {
201204
return _foreignIndex(i, offsetBy: n)
202205
}
203206

204-
if n.magnitude <= _StringBreadcrumbs.breadcrumbStride, !_guts.isASCII {
207+
let threshold = (
208+
i == startIndex ? _breadcrumbStride / 2 : _breadcrumbStride)
209+
if n.magnitude < threshold, !_guts.isASCII {
205210
// Do not use breadcrumbs if directly computing the result is expected to
206211
// be cheaper.
207212
return _index(i, offsetBy: n)._knownUTF8
@@ -225,7 +230,9 @@ extension String.UTF16View: BidirectionalCollection {
225230
return _foreignIndex(i, offsetBy: n, limitedBy: limit)
226231
}
227232

228-
if n.magnitude <= _StringBreadcrumbs.breadcrumbStride, !_guts.isASCII {
233+
let threshold = (
234+
_breadcrumbStride + (i == startIndex ? 0 : _breadcrumbStride / 2))
235+
if n.magnitude < threshold, !_guts.isASCII {
229236
// Do not use breadcrumbs if directly computing the result is expected to
230237
// be cheaper.
231238
return _index(i, offsetBy: n, limitedBy: limit)?._knownUTF8
@@ -268,10 +275,10 @@ extension String.UTF16View: BidirectionalCollection {
268275
}
269276

270277
let utf8Distance = end._encodedOffset - start._encodedOffset
271-
if
272-
utf8Distance.magnitude <= _StringBreadcrumbs.breadcrumbStride,
273-
!_guts.isASCII
274-
{
278+
let threshold = (start == startIndex || end == startIndex
279+
? _breadcrumbStride / 2
280+
: _breadcrumbStride)
281+
if utf8Distance.magnitude < threshold, !_guts.isASCII {
275282
// Do not use breadcrumbs if directly computing the result is expected to
276283
// be cheaper. The conservative threshold above assumes that each UTF-16
277284
// code unit will map to a single UTF-8 code unit, i.e., the worst

0 commit comments

Comments
 (0)