Skip to content

Instantly share code, notes, and snippets.

@airspeedswift
Last active November 25, 2015 18:50
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save airspeedswift/760112f26b31b2c02608 to your computer and use it in GitHub Desktop.
Save airspeedswift/760112f26b31b2c02608 to your computer and use it in GitHub Desktop.
Timing the difference between protocols and protocol-constrained generics
import Darwin
import CoreFoundation.CFDate
protocol NumberGeneratorType {
mutating func generateNumber() -> Int
}
struct RandomGenerator: NumberGeneratorType {
func generateNumber() -> Int {
return Int(arc4random_uniform(10))
}
}
struct IncrementingGenerator: NumberGeneratorType {
var n: Int
init(start: Int) { n = start }
mutating func generateNumber() -> Int {
n += 1
return n
}
}
struct ConstantGenerator: NumberGeneratorType {
let n: Int
init(constant: Int) { n = constant }
func generateNumber() -> Int {
return n
}
}
func generateUsingProtocol(var g: NumberGeneratorType, count: Int) -> Int {
return reduce(stride(from: 0, to: count, by: 1), 0) { total, _ in
total &+ g.generateNumber()
}
}
func generateUsingGeneric<T: NumberGeneratorType>(var g: T, count: Int) -> Int {
return reduce(stride(from: 0, to: count, by: 1), 0) { total, _ in
total &+ g.generateNumber()
}
}
extension String {
func lpad(#to: Int, with: Character) -> String {
let pad = to - count(self)
return pad > 0
? String(count: pad, repeatedValue: with) + self
: self
}
}
func timeRun<T>(name: String, f: ()->T) -> String {
let start = CFAbsoluteTimeGetCurrent()
let result = f()
let end = CFAbsoluteTimeGetCurrent()
let timeStr = toString(Int((end - start) * 1_000_000)).lpad(to: 12, with: " ")
return "\(name)\t\(timeStr)µs, produced \(result)"
}
let n = 10_000_000
let seed = Int(arc4random_uniform(10))
let runs = [
("Generic rand", { generateUsingGeneric(RandomGenerator(), n) }),
("Protocol rand", { generateUsingProtocol(RandomGenerator(), n) }),
("Generic const", { generateUsingGeneric(ConstantGenerator(constant: seed), n) }),
("Protocol const", { generateUsingProtocol(ConstantGenerator(constant: seed), n) }),
("Generic incr", { generateUsingGeneric(IncrementingGenerator(start: seed), n) }),
("Protocol incr", { generateUsingProtocol(IncrementingGenerator(start: seed), n) }),
]
println("\n".join(map(runs, timeRun)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment