Skip to content

Commit fce428e

Browse files
committed
[stdlib] String.UTF16View: Tweak ASCII paths
1 parent 7d89d62 commit fce428e

File tree

1 file changed

+41
-18
lines changed

1 file changed

+41
-18
lines changed

stdlib/public/core/StringUTF16View.swift

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -204,12 +204,14 @@ extension String.UTF16View: BidirectionalCollection {
204204
return _foreignIndex(i, offsetBy: n)
205205
}
206206

207-
let threshold = (
208-
i == startIndex ? _breadcrumbStride / 2 : _breadcrumbStride)
209-
if n.magnitude < threshold, !_guts.isASCII {
210-
// Do not use breadcrumbs if directly computing the result is expected to
211-
// be cheaper.
212-
return _index(i, offsetBy: n)._knownUTF8
207+
if !_guts.isASCII { // We have ASCII fast paths below
208+
let threshold = (
209+
i == startIndex ? _breadcrumbStride / 2 : _breadcrumbStride)
210+
if n.magnitude < threshold {
211+
// Do not use breadcrumbs if directly computing the result is expected to
212+
// be cheaper.
213+
return _index(i, offsetBy: n)._knownUTF8
214+
}
213215
}
214216

215217
let lowerOffset = _nativeGetOffset(for: i)
@@ -230,12 +232,14 @@ extension String.UTF16View: BidirectionalCollection {
230232
return _foreignIndex(i, offsetBy: n, limitedBy: limit)
231233
}
232234

233-
let threshold = (
234-
_breadcrumbStride + (i == startIndex ? 0 : _breadcrumbStride / 2))
235-
if n.magnitude < threshold, !_guts.isASCII {
236-
// Do not use breadcrumbs if directly computing the result is expected to
237-
// be cheaper.
238-
return _index(i, offsetBy: n, limitedBy: limit)?._knownUTF8
235+
if !_guts.isASCII { // We have ASCII fast paths below
236+
let threshold = (
237+
_breadcrumbStride + (i == startIndex ? 0 : _breadcrumbStride / 2))
238+
if n.magnitude < threshold {
239+
// Do not use breadcrumbs if directly computing the result is expected to
240+
// be cheaper.
241+
return _index(i, offsetBy: n, limitedBy: limit)?._knownUTF8
242+
}
239243
}
240244

241245
let iOffset = _nativeGetOffset(for: i)
@@ -275,17 +279,23 @@ extension String.UTF16View: BidirectionalCollection {
275279
}
276280

277281
let utf8Distance = end._encodedOffset - start._encodedOffset
282+
283+
if _guts.isASCII {
284+
return utf8Distance
285+
}
286+
278287
let threshold = (start == startIndex || end == startIndex
279288
? _breadcrumbStride / 2
280289
: _breadcrumbStride)
281-
if utf8Distance.magnitude < threshold, !_guts.isASCII {
290+
if utf8Distance.magnitude < threshold {
282291
// Do not use breadcrumbs if directly computing the result is expected to
283292
// be cheaper. The conservative threshold above assumes that each UTF-16
284293
// code unit will map to a single UTF-8 code unit, i.e., the worst
285294
// possible (a.k.a. most compact) case with all ASCII scalars.
286295
// FIXME: Figure out if a more optimistic threshold would work better.
287296
return _utf16Distance(from: start, to: end)
288297
}
298+
289299
let lower = _nativeGetOffset(for: start)
290300
let upper = _nativeGetOffset(for: end)
291301
return upper &- lower
@@ -309,7 +319,14 @@ extension String.UTF16View: BidirectionalCollection {
309319
let upper = _foreignIndex(lower, offsetBy: offsets.count)
310320
return Range(uncheckedBounds: (lower, upper))
311321
}
312-
if offsets.count < _breadcrumbStride / 2, !_guts.isASCII {
322+
323+
if _guts.isASCII {
324+
let lower = self.index(start, offsetBy: offsets.lowerBound)
325+
let upper = self.index(lower, offsetBy: offsets.count)
326+
return Range(uncheckedBounds: (lower, upper))
327+
}
328+
329+
if offsets.count < _breadcrumbStride / 2 {
313330
let lower = self.index(start, offsetBy: offsets.lowerBound)
314331
let upper = _index(lower, offsetBy: offsets.count)._knownUTF8
315332
return Range(uncheckedBounds: (lower, upper))
@@ -348,11 +365,18 @@ extension String.UTF16View: BidirectionalCollection {
348365
}
349366

350367
let utf8Distance = upper._encodedOffset - lower._encodedOffset
351-
if utf8Distance.magnitude <= _breadcrumbStride / 2, !_guts.isASCII {
368+
369+
if _guts.isASCII {
370+
let lowerOffset = lower._encodedOffset - start._encodedOffset
371+
return Range(uncheckedBounds: (lowerOffset, lowerOffset + utf8Distance))
372+
}
373+
374+
if utf8Distance.magnitude <= _breadcrumbStride / 2 {
352375
let lowerOffset = distance(from: start, to: lower)
353376
let distance = _utf16Distance(from: lower, to: upper)
354377
return Range(uncheckedBounds: (lowerOffset, lowerOffset + distance))
355378
}
379+
356380
let bias = _nativeGetOffset(for: start)
357381
let utf8StartOffset = lower._encodedOffset - start._encodedOffset
358382
let lowerOffset = (
@@ -798,13 +822,12 @@ extension String.UTF16View {
798822
@_effects(releasenone)
799823
internal func _nativeGetOffset(for idx: Index) -> Int {
800824
_internalInvariant(idx._encodedOffset <= _guts.count)
801-
// Trivial and common: start
802-
if idx == startIndex { return 0 }
803-
804825
if _guts.isASCII {
805826
_internalInvariant(idx.transcodedOffset == 0)
806827
return idx._encodedOffset
807828
}
829+
// Trivial and common: start
830+
if idx == startIndex { return 0 }
808831

809832
let idx = _utf16AlignNativeIndex(idx)
810833

0 commit comments

Comments
 (0)