Skip to content

Commit e536ad2

Browse files
committed
[string] Outline cold path from initializer
Outline the cold, non-contiguous UTF-8 path from String(decoding:as:), saving ~40 bytes (33%) of code size (x86_64 and arm64) from every call site where the contiguity check cannot be constant folded away.
1 parent c263100 commit e536ad2

File tree

1 file changed

+17
-8
lines changed

1 file changed

+17
-8
lines changed

stdlib/public/core/String.swift

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,22 @@ extension String {
388388
}
389389

390390
extension String {
391+
// This force type-casts element to UInt8, since we cannot currently
392+
// communicate to the type checker that we proved this with our dynamic
393+
// check in String(decoding:as:).
394+
@_alwaysEmitIntoClient
395+
@inline(never) // slow-path
396+
private static func _fromNonContiguousUnsafeBitcastUTF8Repairing<
397+
C: Collection
398+
>(_ input: C) -> (result: String, repairsMade: Bool) {
399+
_internalInvariant(C.Element.self == UInt8.self)
400+
return Array(input).withUnsafeBufferPointer {
401+
let raw = UnsafeRawBufferPointer($0)
402+
return String._fromUTF8Repairing(raw.bindMemory(to: UInt8.self))
403+
}
404+
}
405+
406+
391407
/// Creates a string from the given Unicode code units in the specified
392408
/// encoding.
393409
///
@@ -406,7 +422,6 @@ extension String {
406422
codeUnits, encoding: sourceEncoding, repair: true)!.0
407423
return
408424
}
409-
410425
if let str = codeUnits.withContiguousStorageIfAvailable({
411426
(buffer: UnsafeBufferPointer<C.Element>) -> String in
412427
return String._fromUTF8Repairing(
@@ -416,13 +431,7 @@ extension String {
416431
return
417432
}
418433

419-
// Just copying to an Array is significantly faster than performing
420-
// generic operations
421-
self = Array(codeUnits).withUnsafeBufferPointer {
422-
let raw = UnsafeRawBufferPointer($0)
423-
return String._fromUTF8Repairing(raw.bindMemory(to: UInt8.self)).0
424-
}
425-
return
434+
self = String._fromNonContiguousUnsafeBitcastUTF8Repairing(codeUnits).0
426435
}
427436

428437
/// Creates a new string with the specified capacity in UTF-8 code units, and

0 commit comments

Comments
 (0)