I'm finally familiar enough with Unsafe…Pointer types in Swift to try to address how the following code was marked as unsafe by XCode.
let pixelBuffer = UnsafeMutablePointer<UInt32>(&pixels)
let bytes = UnsafeRawPointer(pixelBuffer).assumingMemoryBound(to: UInt8.self)
destination.assign(from: bytes, count: pixels.count * 4)
This generated the warning "Initialization of 'UnsafeMutablePointer' results in a dangling pointer". It also runs without error and in approximately 0.00056 seconds. I've found two potential solutions, but both run slower
For the sake of clarity:
var pixels: [UInt32] = …
let destination: UnsafeMutablePointer<UInt8> = …
let destinationCount = pixels.count * 4
I've come up with two alternatives, both of which are considerably slower. This executes in 0.00364 seconds. As I understand the documentation, Data(buffer:) performs a copy, meaning this copies twice:
pixels.withUnsafeMutableBufferPointer { pixelBuffer in
let data = Data(buffer: pixelBuffer)
data.copyBytes(to: destination, count: destinationCount)
}
This executes in 0.02529 seconds.
pixels.withUnsafeBytes { pixelBytes in
let pointer = UnsafeMutableRawBufferPointer(start: destination, count: destinationCount)
pointer.copyBytes(from: pixelBytes)
}
I would have suspected that due to less copying, the second solution would be faster but clearly it's not. Overall this is all negligible but I really want to understand what's going on here, and why a two-copy solution executes in 1/7 the time.
For benchmarking I'm taking the interval between to Date() objects from directly before and after the block is executed.