There’s a lot of hard work going on in this direction and while I hear the complaints I do believe this moves us further in the direction we all want which is important.
Thanks! I'd missed that.
Holy cow. I know I'm late to discover this, having stepped away from the bleeding-edge of Swift for a few months due to needing to prioritize some other things for a bit, but thank you for this. Thank you thank you thank you.
If either of you two guys are ever in Chicago, I will totally treat you to pizza and drinks.
Happy we were able to help move the needle here in an appreciable way.
Thank you for posting those single-source benchmarks. I've been working on a small program (in Swift 3) that opens image and text files and iterates over them, but found working with Data type directly to be very slow. Using the code from the IterateData
benchmark,
datavariable.withUnsafeMutableBytes { (dataPt: UnsafeMutablePointer<UInt8>) -> () in for i in 0..<n { dataPt[i] = something // or something = dataPt[i] }
greatly sped the program up and meant it no longer needed to allocate an array to put the contents of datavariable
into first. On Time Profiler, the biggest time users were the Data subscript getter and setter (' callq "DYLD-STUB$$Data.subscript.setter"
', etc), but that's probably standard for a bridging type like Data.
One question: how might this closure be made an extension of Data? I'm still learning about closures and can never quite figure how to make it a return type.
… and I worked out that problem too: I remembered part of my code was still iterating directly with Data[i]
. Once I replaced that with UnsafeMutablePointer
, the subscript getters/setters disappeared from profiling and the program ran faster still. I've read a few posts here about the problems with Data, but so far I'm finding it useful.
Unexpected follow-up:
In my previously-mentioned program, I had a section where contents of a Data
object initialises an UnsafeMutablePointer<UInt8>
. The code was basically:
// dataFile is a Data instance of length len
var pointer = UnsafeMutablePointer<UInt8>.allocate(capacity: len)
dataFile.withUnsafeMutableBytes { (dfPt: UnsafeMutablePointer<UInt8>) in
pointer.moveInitialize(from: dfPt, count: processLen)
}
I've just migrated to Swift 5 and the compiler tells me this set-up is deprecated. So how might I initialise the pointer from dataFile
's UnsafeMutableRawBufferPointer
? (I've checked SwiftDoc.org on both types, but I'm still not clear on how to convert.)
You should use one of the Data.copyBytes()
methods instead.
That works nicely. Thanks.