Skip to content

Commit fc757d3

Browse files
committed
_StringGuts._extractSlice: Quickly return an empty string when the range is empty
There is little point to allocating String storage with capacity 0.
1 parent 69a2c84 commit fc757d3

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

stdlib/public/core/StringGuts.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,7 @@ extension _StringGuts {
979979
@_inlineable
980980
public // @testable
981981
func _extractSlice(_ range: Range<Int>) -> _StringGuts {
982+
if range.isEmpty { return _StringGuts() }
982983
if range == 0..<count { return self }
983984
switch (isASCII, _isUnmanaged) {
984985
case (true, true):

validation-test/stdlib/String.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,26 @@ StringTests.test("appendToEmptyString") {
521521
expectEqual(b2.bufferID, b2ID)
522522
}
523523

524+
StringTests.test("Swift3Slice/Empty") {
525+
let size = 5
526+
let s = String(repeating: "x", count: size)
527+
for i in 0 ... size {
528+
let slice = s[s.index(_nth: i)..<s.index(_nth: i)]
529+
// Most Swift 3 substrings are extracted into their own buffer,
530+
// but empty substrings get turned into the empty string singleton
531+
expectNil(slice.bufferID)
532+
}
533+
}
534+
535+
StringTests.test("Swift3Slice/Full") {
536+
let size = 5
537+
let s = String(repeating: "x", count: size)
538+
let slice = s[s.startIndex..<s.endIndex]
539+
// Most Swift 3 substrings are extracted into their own buffer,
540+
// but if the substring covers the full original string, it is used instead.
541+
expectEqual(slice.bufferID, s.bufferID)
542+
}
543+
524544
StringTests.test("appendToSubstring") {
525545
for initialSize in 1..<16 {
526546
for sliceStart in [0, 2, 8, initialSize] {

0 commit comments

Comments
 (0)