Skip to content

Commit 7240ee2

Browse files
committed
Speedup for NSString -getCharacters:range:
1 parent 9aabdda commit 7240ee2

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

Foundation.xcodeproj/xcshareddata/xcschemes/SwiftFoundation.xcscheme

+23
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,20 @@
2020
ReferencedContainer = "container:Foundation.xcodeproj">
2121
</BuildableReference>
2222
</BuildActionEntry>
23+
<BuildActionEntry
24+
buildForTesting = "YES"
25+
buildForRunning = "YES"
26+
buildForProfiling = "YES"
27+
buildForArchiving = "YES"
28+
buildForAnalyzing = "YES">
29+
<BuildableReference
30+
BuildableIdentifier = "primary"
31+
BlueprintIdentifier = "5B5D86DA1BBC74AD00234F36"
32+
BuildableName = "SwiftXCTest.framework"
33+
BlueprintName = "SwiftXCTest"
34+
ReferencedContainer = "container:../swift-corelibs-xctest/XCTest.xcodeproj">
35+
</BuildableReference>
36+
</BuildActionEntry>
2337
</BuildActionEntries>
2438
</BuildAction>
2539
<TestAction
@@ -29,6 +43,15 @@
2943
shouldUseLaunchSchemeArgsEnv = "YES">
3044
<Testables>
3145
</Testables>
46+
<MacroExpansion>
47+
<BuildableReference
48+
BuildableIdentifier = "primary"
49+
BlueprintIdentifier = "5B5D885C1BBC938800234F36"
50+
BuildableName = "SwiftFoundation.framework"
51+
BlueprintName = "SwiftFoundation"
52+
ReferencedContainer = "container:Foundation.xcodeproj">
53+
</BuildableReference>
54+
</MacroExpansion>
3255
<AdditionalOptions>
3356
</AdditionalOptions>
3457
</TestAction>

Foundation/NSString.swift

+13-3
Original file line numberDiff line numberDiff line change
@@ -343,8 +343,18 @@ open class NSString : NSObject, NSCopying, NSMutableCopying, NSSecureCoding, NSC
343343

344344
extension NSString {
345345
public func getCharacters(_ buffer: UnsafeMutablePointer<unichar>, range: NSRange) {
346-
for idx in 0..<range.length {
347-
buffer[idx] = character(at: idx + range.location)
346+
if type(of: self) == NSString.self || type(of: self) == NSMutableString.self {
347+
let utf16 = _storage.utf16
348+
var idx = utf16.index(utf16.startIndex, offsetBy: range.location)
349+
for offset in 0..<range.length {
350+
buffer[offset] = utf16[idx]
351+
idx = utf16.index(after: idx)
352+
}
353+
} else {
354+
//TODO: fast paths for _fastContents != nil / _fastCString != nil
355+
for idx in 0..<range.length {
356+
buffer[idx] = character(at: idx + range.location)
357+
}
348358
}
349359
}
350360

@@ -368,7 +378,7 @@ extension NSString {
368378
if type(of: self) == NSString.self || type(of: self) == NSMutableString.self {
369379
let start = _storage.utf16.startIndex
370380
let min = _storage.utf16.index(start, offsetBy: range.location)
371-
let max = _storage.utf16.index(start, offsetBy: range.location + range.length)
381+
let max = _storage.utf16.index(min, offsetBy: range.length)
372382
return String(decoding: _storage.utf16[min..<max], as: UTF16.self)
373383
} else {
374384
let buff = UnsafeMutablePointer<unichar>.allocate(capacity: range.length)

0 commit comments

Comments
 (0)