Recently I have had a very humbling and sobering experience with global variables. Don't let them affect your measurements and your judgment.
Can you spot the victim in the following code?
Code
import Foundation
@main
enum ForOrWhileLoop {
static func main () {
measure (prefix: "T1", f: T1)
measure (prefix: "T2", f: T2)
measure (prefix: "T3", f: T3)
measure (prefix: "T4", f: T4)
measure (prefix: "T5", f: T5)
}
}
let M = 1_000_000
let uv: [Int] = .init (unsafeUninitializedCapacity: M) { buffer, initializedCount in
for i in 0..<M {
buffer [i] = Int.random(in: 0..<1024)
}
initializedCount = M
}
func measure (prefix: String, f: () -> Int) {
let c = ContinuousClock ()
let d = c.measure {
_ = f ()
}
print ("M = \(M)", prefix, "took", d)
}
func T1 () -> Int {
var sum: Int = 0
for u in uv {
sum += u
}
return sum
}
func T2 () -> Int {
var sum: Int = 0
for i in 0..<M {
sum += uv [i]
}
return sum
}
func T3 () -> Int {
var sum: Int = 0
var i: Int = 0
while i < M {
sum += uv [i]
i += 1
}
return sum
}
func T4 () -> Int {
let sum = uv.reduce (0) { partialResult, u in
partialResult + u
}
return sum
}
func T5 () -> Int {
var sum: Int = 0
uv.withUnsafeBufferPointer {
var i: Int = 0
while i < M {
sum += $0 [i]
i += 1
}
}
return sum
}
If you can't, then head over to this post, and then this post.