Skip to content

Commit 5ba5be3

Browse files
committed
[String] Speed up UTF-8 initialization from non-stdlib types
Avoid generic code paths if initializing for UTF-8 (the vast majority of the time) from a non-stdlib type (such as Data).
1 parent 706f15f commit 5ba5be3

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

stdlib/public/core/String.swift

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,13 @@ extension String {
401401
public init<C: Collection, Encoding: Unicode.Encoding>(
402402
decoding codeUnits: C, as sourceEncoding: Encoding.Type
403403
) where C.Iterator.Element == Encoding.CodeUnit {
404+
guard _fastPath(sourceEncoding == UTF8.self) else {
405+
self = String._fromCodeUnits(
406+
codeUnits, encoding: sourceEncoding, repair: true)!.0
407+
return
408+
}
409+
404410
if let contigBytes = codeUnits as? _HasContiguousBytes,
405-
sourceEncoding == UTF8.self,
406411
contigBytes._providesContiguousBytesNoCopy
407412
{
408413
self = contigBytes.withUnsafeBytes { rawBufPtr in
@@ -414,8 +419,13 @@ extension String {
414419
return
415420
}
416421

417-
self = String._fromCodeUnits(
418-
codeUnits, encoding: sourceEncoding, repair: true)!.0
422+
// Just copying to an Array is significantly faster than performing
423+
// generic operations
424+
self = Array(codeUnits).withUnsafeBufferPointer {
425+
let raw = UnsafeRawBufferPointer($0)
426+
return String._fromUTF8Repairing(raw.bindMemory(to: UInt8.self)).0
427+
}
428+
return
419429
}
420430

421431
/// Calls the given closure with a pointer to the contents of the string,

0 commit comments

Comments
 (0)