Comparing speed of generic function vs. Slice -> Array conversion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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