Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- extension String {
- /// The base address of the contiguous buffer containing the String elements
- /// if the String is backed by a contiguous buffer.
- ///
- /// There is no guarantee that the String is backed by a contiguous buffer.
- /// Even if it is, there is no guarantee that the buffer is writable.
- public var baseAddress: UnsafeRawPointer? {
- return UnsafeRawPointer(self._core._baseAddress)
- }
- /// The number of elements stored in the buffer.
- ///
- /// The count must not be increased beyond the buffer size for an immutable buffer
- /// or capacity for a mutable buffer.
- public var elementCount: Int {
- get {
- return self._core.count
- }
- set {
- self._core.count = newValue
- }
- }
- /// The read-only width of the elements stored in the buffer (1 or 2).
- public var elementWidth: Int {
- return self._core.elementWidth
- }
- /// The read-only capacity of the String buffer if the String is backed by a mutable contiguous buffer.
- public var capacity: Int? {
- if let capacity = self._core.nativeBuffer?.capacity {
- return capacity + 2 - self.elementWidth
- } else {
- return nil
- }
- }
- /// Ensures that the String is backed by a uniquely owned mutable contiguous buffer with at least
- /// the requested capacity and returns the base address of the this buffer.
- ///
- /// This call may require copying the String elements into a new buffer and modifying the element size.
- /// The reserved capacity may be greater than the requested capacity.
- /// Repeated calls with the same or lower capacity requirements are no ops.
- ///
- /// - Parameter capacity: the requested String capacity (number of elements).
- /// - Parameter minElementWidth: the requested minimum element width.
- /// - Returns: the base address of the mutable contiguous buffer backing the String.
- @discardableResult public mutating func claimOwnership(withCapacity capacity: Int? = nil, withMinElementWidth minElementWidth: Int = 1) -> UnsafeMutableRawPointer {
- if self.elementWidth < minElementWidth {
- self.append("\u{a3}") // force element width = 2
- if let capacity = capacity {
- self._core.reserveCapacity(capacity)
- }
- self.elementCount -= 1
- } else {
- self._core.reserveCapacity(capacity ?? 0)
- }
- return self._core.nativeBuffer!.start
- }
- /// Executes action on String buffer.
- ///
- /// Assumes String is backed by uniquely owned mutable contiguous buffer already.
- ///
- /// - Parameter action: the action to execute.
- @inline(__always) public mutating func withUnsafeMutablePointer(execute action: (UnsafeMutablePointer<UInt8>) -> Void) {
- action(self._core.nativeBuffer!.start.assumingMemoryBound(to: UInt8.self))
- }
- }
- import Foundation
- var now = mach_absolute_time()
- var string = "AAA"
- string.claimOwnership()
- for _ in 1...3 {
- // mutate string element using withUnsafe...
- now = mach_absolute_time()
- for i in 0..<100000000 {
- string.withUnsafeMutablePointer { $0.pointee = 65 + UInt8(i % 26) }
- }
- print("closure: \(Double(mach_absolute_time() - now) / 1e6)ms")
- // mutate string element using pointer obtained before entering loop
- now = mach_absolute_time()
- let ptr = string.claimOwnership().assumingMemoryBound(to: UInt8.self)
- for i in 0..<100000000 {
- ptr.pointee = 65 + UInt8(i % 26)
- }
- print("pointer: \(Double(mach_absolute_time() - now) / 1e6)ms")
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement