Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Comparing speed of generic function vs. Slice -> Array conversion
// comparing speed of generic function vs. Slice -> Array conversion
import Foundation
// sum function that takes a Slice<Int>
func sumSlice(numbers: Slice<Int>) -> Int {
return numbers.reduce(0, +)
}
// sum function that takes an Array<Int>
func sumArray(numbers: [Int]) -> Int {
return numbers.reduce(0, +)
}
// sum function that can accept either
func sumGeneric<T, S: Sliceable where T == S.Generator.Element, T : IntegerType>(numbers: S) -> T {
return reduce(numbers, 0, { (lhs, rhs) in lhs + rhs })
}
// time the execution of a code block
func timeBlock(iterations: Int, block: () -> ()) -> NSTimeInterval {
let start = NSDate()
for _ in 1...iterations {
block()
}
return NSDate().timeIntervalSinceDate(start)
}
func timeAll(array: [Int], iterations: Int) -> (NSTimeInterval, NSTimeInterval, NSTimeInterval) {
let count = Int32(array.count)
// time the function using Slice
srand(42)
let sliceTime = timeBlock(iterations) {
let start = Int(rand() % count)
let end = start + Int(rand() % (count - Int32(start)))
sumSlice(array[start..<end])
}
// time the function using Array
srand(42)
let arrayTime = timeBlock(iterations) {
let start = Int(rand() % count)
let end = start + Int(rand() % (count - Int32(start)))
sumArray(Array(array[start..<end]))
}
// time the function using Generic
srand(42)
let genericTime = timeBlock(iterations) {
let start = Int(rand() % count)
let end = start + Int(rand() % (count - Int32(start)))
sumGeneric(array[start..<end])
}
return (sliceTime, arrayTime, genericTime)
}
// setup
let iterations = 500
let maxItems = 1_000
var results = Array<(Int, (Double, Double, Double))>()
// run test
for itemCount in stride(from: 100, through: maxItems, by: 100) {
let array = Array(1...itemCount)
let (sliceTime, arrayTime, genericTime) = timeAll(array, iterations)
results += [(itemCount, (sliceTime, arrayTime, genericTime))]
}
// results
let convertedAverage = results.reduce(0.0) { $0 + $1.1.1 } / Double(results.count)
let genericAverage = results.reduce(0.0) { $0 + $1.1.2 } / Double(results.count)
println("Generic function is \(round(convertedAverage / genericAverage * 100) / 100)x faster than converting to Array")
// Generic function is 6.25x faster than converting to Array
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment