Created
September 18, 2018 19:35
-
-
Save calda/a45259be234b269536c63fd859988c4b to your computer and use it in GitHub Desktop.
Schwartzian Transform experiment
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
import QuartzCore | |
// MARK: Extensions | |
extension Sequence { | |
func sorted<T: Comparable>(by value: (Element) -> T) -> [Self.Element] { | |
return self.sorted(by: { lhs, rhs in | |
return value(lhs) < value(rhs) | |
}) | |
} | |
func sortedSchwartzian<T: Comparable>(by value: (Element) -> T) -> [Self.Element] { | |
return self.map { ($0, value($0)) } | |
.sorted(by: { $0.1 < $1.1 }) | |
.map { $0.0 } | |
} | |
} | |
// MARK: Person | |
struct Person { | |
let name: String | |
let age: Int | |
var arbitraryComplexCalculation: Int { | |
var i = age | |
for _ in 1...1000 { | |
i += 1 | |
} | |
return i | |
} | |
} | |
// MARK: Timing Helpers | |
func executionTime(repeats: Int = 1, block: () -> ()) -> CFTimeInterval { | |
let start = CACurrentMediaTime() | |
for _ in 1...repeats { | |
block(); | |
} | |
let end = CACurrentMediaTime() | |
return (end - start) / Double(repeats) | |
} | |
extension Double { | |
func round(digits: Int) -> Double { | |
let divisor = pow(10.0, Double(digits)) | |
return (self * divisor).rounded() / divisor | |
} | |
} | |
// MARK: Experiments | |
let people = Array(0...10000).map { Person(name: "Person \($0)", age: $0) }.shuffled() | |
// fast block (simple accessor) | |
let simpleAccess_standardSort = executionTime(repeats: 10) { | |
people.sorted(by: { $0.name < $1.name }) | |
} | |
let simpleAccess_closureSort = executionTime(repeats: 10) { | |
people.sorted(by: { $0.name }) | |
} | |
let simpleAccess_schwartzianSort = executionTime(repeats: 10) { | |
people.sortedSchwartzian(by: { $0.name }) | |
} | |
// complex block | |
let complexCalculation_standardSort = executionTime(repeats: 10) { | |
people.sorted(by: { $0.arbitraryComplexCalculation < $1.arbitraryComplexCalculation }) | |
} | |
let complexCalculation_closureSort = executionTime(repeats: 10) { | |
people.sorted(by: { $0.arbitraryComplexCalculation }) | |
} | |
let complexCalculation_schwartzianSort = executionTime(repeats: 10) { | |
people.sortedSchwartzian(by: { $0.arbitraryComplexCalculation }) | |
} | |
// result | |
print(""" | |
Simple Accessor ($0.name) | |
========================= | |
Standard Library Sort:\t \(simpleAccess_standardSort.round(digits: 4))s | |
Closure-Based Sort:\t \(simpleAccess_closureSort.round(digits: 4))s | |
Schwartzian Sort:\t \(simpleAccess_schwartzianSort.round(digits: 4))s | |
Complex Calculation ($0.arbitraryComplexCalculation) | |
========================= | |
Standard Library Sort:\t \(complexCalculation_standardSort.round(digits: 4))s | |
Closure-Based Sort:\t \(complexCalculation_closureSort.round(digits: 4))s | |
Schwartzian Sort:\t \(complexCalculation_schwartzianSort.round(digits: 4))s | |
""") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment