Skip to content

Instantly share code, notes, and snippets.

@Exey
Last active September 23, 2019 12:51
Show Gist options
  • Save Exey/3f58a1c7320d83d66c021a71f350ae11 to your computer and use it in GitHub Desktop.
Save Exey/3f58a1c7320d83d66c021a71f350ae11 to your computer and use it in GitHub Desktop.
Benchmark comparing guard vs. if let
import Foundation
var RUNS = 10
var COUNT = 10_000_000
// Extensions for prints
extension Sequence where Element: BinaryFloatingPoint {
func average() -> Element {
var i: Element = 0
var total: Element = 0
for value in self {
total = total + value
i += 1
}
return total / i
}
}
// Profiler
final class Profiler {
class func measure(_ closure: (() -> Void)!) -> TimeInterval {
let startDate = Date()
closure()
let endDate = Date()
let interval = endDate.timeIntervalSince(startDate)
return interval
}
}
// Test Data
var testData1: String? = "optional string"
var testData2: Int? = 999666
func testFunc(s:String, i:Int) -> Int {
return 2+i
}
// Profilers
func testGuard(_ count: Int) -> TimeInterval {
return Profiler.measure() {
for _ in 1...COUNT {
guard let test1 = testData1, let test2 = testData2 else {
return
}
_ = testFunc(s: test1, i: test2)
}
}
}
func testIf(_ count: Int) -> TimeInterval {
return Profiler.measure() {
for _ in 1...COUNT {
if let test1 = testData1, let test2 = testData2 {
_ = testFunc(s: test1, i: test2)
}
}
}
}
func warm() {
for _ in 1...10_000 {
_ = testFunc(s: fastRandomString(Int.random(in: 5...10)), i: Int.random(in: 0...1000))
}
}
func fastRandomString(_ length: Int)->String{
enum s {
static let c = Array("abcdefghjklmnpqrstuvwxyz12345789")
static let k = UInt32(c.count)
}
var result = [Character](repeating: "-", count: length)
for i in 0..<length {
let r = Int(arc4random_uniform(s.k))
result[i] = s.c[r]
}
return String(result)
}
// Results
#if arch(i386) || arch(x86_64)
print("Device x86_64\n")
#elseif arch(arm64)
print("Device arm64\n")
#else
print("Device Unknown\n")
#endif
// Important Warm
print("WARM please wait…\n")
warm()
// if
var results1 = [Double]()
for i in 1...RUNS {
let t = testIf(COUNT)
results1.append(Double(t))
print("#\(i) IF \(t)")
}
print("IF runs \(RUNS) * \(COUNT) average \(String(describing: results1.average()))")
print("")
// guard
var results2 = [Double]()
for i in 1...RUNS {
let t = testGuard(COUNT)
results2.append(Double(t))
print("#\(i) GUARD \(t)")
}
print("GUARD runs \(RUNS) * \(COUNT) average \(String(describing: results2.average()))")
// total
let (resultMin, resultMax) = (min(results1.average(), results2.average()), max(results1.average(), results2.average()))
print("\nDIFF \(1.0-resultMin/resultMax)")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment