11extension StringProtocol where Self: RangeReplaceableCollection , Self. Element: Equatable {
2- /// Provides a version of `StringProtocol.firstRange(of:)` which is guaranteed to be available on
3- /// pre-Ventura Apple platforms.
2+ /// Provides a version of `StringProtocol.firstRange(of:)` guaranteed to be available.
43 @inlinable
54 func sqlkit_firstRange( of other: some StringProtocol ) -> Range < Self . Index > ? {
6- /// N.B.: This implementation is apparently some 650% faster than `firstRange(of:)`, at least on macOS...
75 guard self . count >= other. count, let starter = other. first else { return nil }
86 var index = self . startIndex
97 let lastIndex = self . index ( self . endIndex, offsetBy: - other. count)
@@ -21,15 +19,17 @@ extension StringProtocol where Self: RangeReplaceableCollection, Self.Element: E
2119 return nil
2220 }
2321
24- /// Provides a version of `StringProtocol.replacing(_:with:)` which is guaranteed to be available on
25- /// pre-Ventura Apple platforms.
22+ /// Provides a version of `StringProtocol.replacing(_:with:)` which is guaranteed to be available.
23+ #if !DEBUG && !canImport(Darwin)
24+ @inline ( __always)
25+ #endif
2626 @inlinable
2727 func sqlkit_replacing( _ search: some StringProtocol , with replacement: some StringProtocol ) -> String {
28- /// N.B.: Even on Ventura/Sonoma, the handwritten implementation is orders of magnitude faster than
29- /// `replacing(_:with:)`, at least as of the time of this writing. Thus we use the handwritten version
30- /// unconditionally. It's still 4x slower than Foundation's version, but that's a lot better than 25x .
28+ #if DEBUG || canImport(Darwin)
29+ // On Apple platforms, this hand-rolled implementation is MUCH faster (10x or more) than the stdlib version, for some reason.
30+ // We also want to use this implementation in debug builds, so that the tests test it rather than the stdlib .
3131 guard !self . isEmpty, !search. isEmpty, self . count >= search. count else { return . init( self ) }
32-
32+
3333 var result = " " , prevIndex = self . startIndex
3434
3535 result. reserveCapacity ( self . count + replacement. count)
@@ -40,6 +40,10 @@ extension StringProtocol where Self: RangeReplaceableCollection, Self.Element: E
4040 }
4141 result. append ( contentsOf: self [ prevIndex... ] )
4242 return result
43+ #else
44+ // On non-Apple platforms, the stdlib's version is better than our hand-rolled one.
45+ return String ( self . replacing ( search, with: replacement) )
46+ #endif
4347 }
4448
4549 /// Returns the string with its first character lowercased.
0 commit comments