Skip to content

Instantly share code, notes, and snippets.

@Vladlex
Last active May 27, 2020 11:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Vladlex/5ddeb769472b7691e50d9c1787675709 to your computer and use it in GitHub Desktop.
Save Vladlex/5ddeb769472b7691e50d9c1787675709 to your computer and use it in GitHub Desktop.
Comparing different reduce algorithms
// ReduceTests.swift
// Created by Gordeev Aleksey on 27.05.2020.
import XCTest
@testable import ReduceTesting
extension Sequence {
func reduce<Result>(
_ initialResult: Result,
_ nextPartialResult: (Result, Self.Iterator.Element) throws -> Result,
until conditionPassForResult: (Result) -> Bool
) rethrows -> Result {
return try reduce(initialResult, {
if conditionPassForResult($0) {
return $0
}
else {
return try nextPartialResult($0, $1)
}
})
}
func improvedReduce<Result>(
_ initialResult: Result,
_ nextPartialResult: (Result, Self.Iterator.Element) throws -> Result,
until conditionPassForResult: (Result) -> Bool
) rethrows -> Result {
var result = initialResult
for item in self {
result = try nextPartialResult(result, item)
guard !conditionPassForResult(result) else {
return result
}
}
return result
}
}
class ReduceTestingTests: XCTestCase {
let elements = (0..<10000).map({ $0 })
func testReduceFuncsGotEqualResults() {
let result1 = elements.reduce(0, +, until: { $0 > 500 })
let result2 = elements.improvedReduce(0, +, until: { $0 > 500 })
XCTAssertEqual(result1, result2)
}
func testOriginalReduce() throws {
// Shows 0.004s (0.00367 actually)
measure {
_ = elements.reduce(0, +, until: { $0 > 500 })
}
}
func testImprovedReduce() {
// Shows 0.000s (0.0000423 actually)
measure {
_ = elements.improvedReduce(0, +, until: { $0 > 500 })
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment