Advertisement
Guest User

Untitled

a guest
Feb 21st, 2017
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.56 KB | None | 0 0
  1. extension String {
  2. /// The base address of the contiguous buffer containing the String elements
  3. /// if the String is backed by a contiguous buffer.
  4. ///
  5. /// There is no guarantee that the String is backed by a contiguous buffer.
  6. /// Even if it is, there is no guarantee that the buffer is writable.
  7. public var baseAddress: UnsafeRawPointer? {
  8. return UnsafeRawPointer(self._core._baseAddress)
  9. }
  10.  
  11. /// The number of elements stored in the buffer.
  12. ///
  13. /// The count must not be increased beyond the buffer size for an immutable buffer
  14. /// or capacity for a mutable buffer.
  15. public var elementCount: Int {
  16. get {
  17. return self._core.count
  18. }
  19. set {
  20. self._core.count = newValue
  21. }
  22. }
  23.  
  24. /// The read-only width of the elements stored in the buffer (1 or 2).
  25. public var elementWidth: Int {
  26. return self._core.elementWidth
  27. }
  28.  
  29. /// The read-only capacity of the String buffer if the String is backed by a mutable contiguous buffer.
  30. public var capacity: Int? {
  31. if let capacity = self._core.nativeBuffer?.capacity {
  32. return capacity + 2 - self.elementWidth
  33. } else {
  34. return nil
  35. }
  36. }
  37.  
  38. /// Ensures that the String is backed by a uniquely owned mutable contiguous buffer with at least
  39. /// the requested capacity and returns the base address of the this buffer.
  40. ///
  41. /// This call may require copying the String elements into a new buffer and modifying the element size.
  42. /// The reserved capacity may be greater than the requested capacity.
  43. /// Repeated calls with the same or lower capacity requirements are no ops.
  44. ///
  45. /// - Parameter capacity: the requested String capacity (number of elements).
  46. /// - Parameter minElementWidth: the requested minimum element width.
  47. /// - Returns: the base address of the mutable contiguous buffer backing the String.
  48. @discardableResult public mutating func claimOwnership(withCapacity capacity: Int? = nil, withMinElementWidth minElementWidth: Int = 1) -> UnsafeMutableRawPointer {
  49. if self.elementWidth < minElementWidth {
  50. self.append("\u{a3}") // force element width = 2
  51. if let capacity = capacity {
  52. self._core.reserveCapacity(capacity)
  53. }
  54. self.elementCount -= 1
  55. } else {
  56. self._core.reserveCapacity(capacity ?? 0)
  57. }
  58. return self._core.nativeBuffer!.start
  59. }
  60.  
  61. /// Executes action on String buffer.
  62. ///
  63. /// Assumes String is backed by uniquely owned mutable contiguous buffer already.
  64. ///
  65. /// - Parameter action: the action to execute.
  66. @inline(__always) public mutating func withUnsafeMutablePointer(execute action: (UnsafeMutablePointer<UInt8>) -> Void) {
  67. action(self._core.nativeBuffer!.start.assumingMemoryBound(to: UInt8.self))
  68. }
  69. }
  70.  
  71. import Foundation
  72.  
  73. var now = mach_absolute_time()
  74. var string = "AAA"
  75. string.claimOwnership()
  76.  
  77. for _ in 1...3 {
  78. // mutate string element using withUnsafe...
  79. now = mach_absolute_time()
  80. for i in 0..<100000000 {
  81. string.withUnsafeMutablePointer { $0.pointee = 65 + UInt8(i % 26) }
  82. }
  83. print("closure: \(Double(mach_absolute_time() - now) / 1e6)ms")
  84.  
  85. // mutate string element using pointer obtained before entering loop
  86. now = mach_absolute_time()
  87. let ptr = string.claimOwnership().assumingMemoryBound(to: UInt8.self)
  88. for i in 0..<100000000 {
  89. ptr.pointee = 65 + UInt8(i % 26)
  90. }
  91. print("pointer: \(Double(mach_absolute_time() - now) / 1e6)ms")
  92. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement