func fibonacci(_ x: Int) -> Int {
x <= 2 ? 1 : fibonacci(x - 1) + fibonacci(x - 2)
}
func memoize<I: Hashable, U>(_ fun: @escaping (I) -> U) -> (I) -> U {
// item cache
var memo = [I: U]()
// send back a new closure that does our calculation
return { x in
if let r = memo[x] { return r }
let r = fun(x)
memo[x] = r
return r
}
}
let memFibonacci = memoize(fibonacci)
for i in 1...2 {
let start = Date()
let f33 = memFibonacci(33)
let seconds = abs(start.timeIntervalSinceNow)
print("\(i): f33 is \(f33)")
print("\(i): seconds33 is \(seconds)")
}
// prints:
// 1: f33 is 3524578
// 1: seconds33 is 0.009974360466003418
// 2: f33 is 3524578
// 2: seconds33 is 4.76837158203125e-07
let start = Date()
let f34 = memFibonacci(34)
let seconds = abs(start.timeIntervalSinceNow)
print("f34 is \(f34)")
print("seconds is \(seconds)")
//f34 is 5702887
//seconds is 0.016646504402160645
| This memoization method works well with non-recursive functions. Because it only remembers the result of the first function call. |