Conversation
|
@dosubot could you review this PR? It optimized |
|
Thanks for working on this performance optimization! The 5-20x improvement benchmarks are impressive, especially the 20x boost for long strings (119µs → 5.5µs). Here's my review: ✅ What Looks Good
|
fortmarek
left a comment
There was a problem hiding this comment.
🤯
Thanks a lot for this PR, the improvements are impressive. I have a couple minor nits, but otherwise, looks good!
| // calculate exact size | ||
| let escapedCapacity = buf.escapedCommentCapacity | ||
|
|
||
| if #available(iOS 14.0, macOS 11.0, tvOS 14.0, watchOS 7.0, visionOS 1.0, *) { |
There was a problem hiding this comment.
I believe we can bump the minimum versions in Package.swift, we don't need to support platforms older than this.
| var escapedCommentCapacity: Int { | ||
| var escapeCount = 0 | ||
|
|
||
| for ch in self { |
There was a problem hiding this comment.
| for ch in self { | |
| for character in self { |
would limit the usage of such short variable names (I would change this across the PR)
|
|
||
| /// Calculates escaped string size | ||
| /// Basically, `count + count(where: { [.backslash, .doubleQuotes, .tab, .newline].contains($0) }` | ||
| var escapedCommentCapacity: Int { |
There was a problem hiding this comment.
we're going through all chars of self, so I think this should be a method instead of a computed variable (same goes for the other computed properties in this extension)
Resolves #1066
Short description 📝
Solution 📦
StringProtocol.containswith checking that oneUInt8array (specificallyUnsafeBufferPointer) is subarray of another. Why this approach is faster? BecauseStringProtocol.containsspends most of its time on string indexing (which requires much logic to preserve grapheme clusters).rangeOfCharacterwith checking thatUInt8array (specificallyUnsafeBufferPointer) contains specific value.appendfor each string character inreducefunction - calculate needed capacity upfront and createStringusingString(unsafeUninitializedCapacity:)initImplementation 👩💻👨💻
StringProtocol.containsandrangeOfCharacterswithUnsafeBufferPointer<UInt8>operationsreduce+append. It required too much memory allocation. Instead - calculate needed capacity upfront and createStringusingString(unsafeUninitializedCapacity:)initPerformance
Performance Comparison
Measured with
M2 Max 32 GB RAM, MacOS 26.2, release build. If I run these benchmarks many times, average deviation is about 3-4%Previous
validStringimplementation performance:Introduced
validStringimplementation performance: