Skip to content

Instantly share code, notes, and snippets.

@mishagray
Created January 11, 2015 23:13
Show Gist options
  • Save mishagray/4c25056273fd9c82a813 to your computer and use it in GitHub Desktop.
Save mishagray/4c25056273fd9c82a813 to your computer and use it in GitHub Desktop.
Comparing the speed difference between NSMutableData and <CUnsignedChar>.alloc
/* OS X Swift "Command Line Tool" */
import Foundation
extension NSData {
func jstnMD5() -> String {
let result = NSMutableData(length: Int(CC_MD5_DIGEST_LENGTH))!
let resultBytes = UnsafeMutablePointer<CUnsignedChar>(result.mutableBytes)
CC_MD5(self.bytes, CC_LONG(self.length), resultBytes)
let a = UnsafeBufferPointer<CUnsignedChar>(start: resultBytes, count: result.length)
let hash = NSMutableString()
for i in a {
hash.appendFormat("%02x", i)
}
return hash
}
func jstnMD5Auto() {
autoreleasepool {
self.jstnMD5()
return
}
}
func mgrayMD5() -> String {
let digestLen = Int(CC_MD5_DIGEST_LENGTH)
let result = UnsafeMutablePointer<CUnsignedChar>.alloc(digestLen)
CC_MD5(self.bytes, CC_LONG(self.length), result)
var hash = NSMutableString()
for i in 0..<digestLen {
hash.appendFormat("%02x", result[i])
}
result.dealloc(digestLen)
return hash
}
func mgrayMD5Auto() {
autoreleasepool {
self.mgrayMD5()
return
}
}
}
struct Benchmarker {
static var t = mach_timebase_info(numer: 0, denom: 0)
var startTime: UInt64 = 0
var duration: UInt64 = 0
init() {
if Benchmarker.t.denom == 0 {
mach_timebase_info(&Benchmarker.t)
}
}
func measureBlock(block:() -> Void) -> UInt64 {
let startTime = mach_absolute_time()
block()
let delta = mach_absolute_time() - startTime
let duration = (delta * UInt64(Benchmarker.t.numer)) / UInt64(Benchmarker.t.denom)
return duration
}
mutating func start() {
startTime = mach_absolute_time()
}
mutating func stop() {
let delta = mach_absolute_time() - startTime
duration = (delta * UInt64(Benchmarker.t.numer)) / UInt64(Benchmarker.t.denom)
}
}
var bench = Benchmarker()
let count: UInt64 = 25_000
println("prepping...")
// let's make a big string! Cause that will expose limits
var bigStringToHash = NSMutableString()
let NUMBER_OF_HEX_VALUES = 1024
for i in 0 ..< NUMBER_OF_HEX_VALUES {
bigStringToHash.appendFormat("%02x", i)
}
let bigDataToHash = (bigStringToHash as NSString).dataUsingEncoding(NSUTF8StringEncoding)!
println("benchmarking...")
println()
var mgrayTotal: UInt64 = 0
mgrayTotal += bench.measureBlock {
for i in 0 ..< count {
bigDataToHash.mgrayMD5()
}
}
let mgrayAvg = ((Double(mgrayTotal) / Double(count))) / 1_000_000
println("mgray method took an average of \(mgrayAvg) milliseconds")
var mgrayAutoTotal: UInt64 = 0
mgrayAutoTotal += bench.measureBlock {
for i in 0 ..< count {
bigDataToHash.mgrayMD5Auto()
}
}
let mgrayAvgAuto = ((Double(mgrayAutoTotal) / Double(count))) / 1_000_000
println("mgrayAuto method took an average of \(mgrayAvgAuto) milliseconds")
var jstnTotal: UInt64 = 0
jstnTotal += bench.measureBlock {
for i in 0 ..< count {
bigDataToHash.jstnMD5()
}
}
let jstnAvg = ((Double(jstnTotal) / Double(count))) / 1_000_000
println("jstn method took an average of \(jstnAvg) milliseconds")
var jstnAutoTotal: UInt64 = 0
jstnAutoTotal += bench.measureBlock {
for i in 0 ..< count {
bigDataToHash.jstnMD5Auto()
}
}
let jstnAutoAvg = ((Double(jstnAutoTotal) / Double(count))) / 1_000_000
println("jstnAuto method took an average of \(jstnAutoAvg) milliseconds")
let fastest = min(min(jstnAvg,mgrayAvg),min(jstnAutoAvg,mgrayAvgAuto))
println("jstn slowerBy \(jstnAvg/fastest - 1.0)%")
println("mgray slowerBy \(mgrayAvg/fastest - 1.0)%")
println("jstnAuto slowerBy \(jstnAutoAvg/fastest - 1.0)%")
println("mgrayAuto slowerBy \(mgrayAvgAuto/fastest - 1.0)%")
/*
mgray method took an average of 0.28074134496 milliseconds
mgrayAuto method took an average of 0.27791677304 milliseconds
jstn method took an average of 0.28209413156 milliseconds
jstnAuto method took an average of 0.28173894976 milliseconds
jstn slowerBy 0.0150309694312649%
mgray slowerBy 0.0101633733333306%
jstnAuto slowerBy 0.0137529544481645%
mgrayAuto slowerBy 0.0%
Program ended with exit code: 0
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment