Skip to content

Commit 220883f

Browse files
Sequence algorithm benchmarks (#14663)
1 parent 2d9e429 commit 220883f

File tree

3 files changed

+136
-0
lines changed

3 files changed

+136
-0
lines changed

benchmark/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ set(SWIFT_BENCH_MODULES
124124
single-source/ReduceInto
125125
single-source/ReversedCollections
126126
single-source/RomanNumbers
127+
single-source/SequenceAlgos
127128
single-source/SetTests
128129
single-source/SevenBoom
129130
single-source/Sim2DArray
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
//===--- ArrayAppend.swift ------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
14+
import TestsUtils
15+
16+
// This benchmark tests closureless versions of min and max, both contains,
17+
// repeatElement and reduce, on a number of different sequence types.
18+
// To avoid too many little micro benchmarks, it measures them all together
19+
// for each sequence type.
20+
21+
public let SequenceAlgos = [
22+
BenchmarkInfo(name: "SequenceAlgosList", runFunction: run_SequenceAlgosList, tags: [.validation, .api], setUpFunction: { buildWorkload() }, tearDownFunction: nil),
23+
BenchmarkInfo(name: "SequenceAlgosArray", runFunction: run_SequenceAlgosArray, tags: [.validation, .api], setUpFunction: { buildWorkload() }, tearDownFunction: nil),
24+
BenchmarkInfo(name: "SequenceAlgosContiguousArray", runFunction: run_SequenceAlgosContiguousArray, tags: [.validation, .api], setUpFunction: { buildWorkload() }, tearDownFunction: nil),
25+
BenchmarkInfo(name: "SequenceAlgosRange", runFunction: run_SequenceAlgosRange, tags: [.validation, .api], setUpFunction: { buildWorkload() }, tearDownFunction: nil),
26+
BenchmarkInfo(name: "SequenceAlgosUnfoldSequence", runFunction: run_SequenceAlgosUnfoldSequence, tags: [.validation, .api], setUpFunction: { buildWorkload() }, tearDownFunction: nil),
27+
BenchmarkInfo(name: "SequenceAlgosAnySequence", runFunction: run_SequenceAlgosAnySequence, tags: [.validation, .api], setUpFunction: { buildWorkload() }, tearDownFunction: nil),
28+
]
29+
30+
extension List: Sequence {
31+
struct Iterator: IteratorProtocol {
32+
var _list: List<Element>
33+
mutating func next() -> Element? {
34+
guard case let .node(x,xs) = _list else { return nil }
35+
_list = xs
36+
return x
37+
}
38+
}
39+
func makeIterator() -> Iterator {
40+
return Iterator(_list: self)
41+
}
42+
}
43+
44+
extension List: Equatable where Element: Equatable {
45+
static func == (lhs: List<Element>, rhs: List<Element>) -> Bool {
46+
return lhs.elementsEqual(rhs)
47+
}
48+
}
49+
50+
func benchmarkSequenceAlgos<S: Sequence>(s: S, n: Int) where S.Element == Int {
51+
CheckResults(s.reduce(0, &+) == (n*(n-1))/2)
52+
let mn = s.min()
53+
let mx = s.max()
54+
CheckResults(mn == 0 && mx == n-1)
55+
CheckResults(s.starts(with: s))
56+
}
57+
58+
let n = 10_000
59+
let r = 0..<(n*100)
60+
let l = List(0..<n)
61+
let c = ContiguousArray(0..<(n*100))
62+
let a = Array(0..<(n*100))
63+
let y = AnySequence(0..<n)
64+
let s = sequence(first: 0, next: { $0 < n&-1 ? $0&+1 : nil})
65+
66+
func buildWorkload() {
67+
_ = l.makeIterator()
68+
_ = c.makeIterator()
69+
_ = a.makeIterator()
70+
_ = y.makeIterator()
71+
_ = s.makeIterator()
72+
}
73+
74+
func benchmarkEquatableSequenceAlgos<S: Sequence>(s: S, n: Int) where S.Element == Int, S: Equatable {
75+
CheckResults(repeatElement(s, count: 1).contains(s))
76+
CheckResults(!repeatElement(s, count: 1).contains { $0 != s })
77+
}
78+
79+
@inline(never)
80+
public func run_SequenceAlgosRange(_ N: Int) {
81+
for _ in 0..<N {
82+
benchmarkSequenceAlgos(s: r, n: r.count)
83+
benchmarkEquatableSequenceAlgos(s: r, n: r.count)
84+
}
85+
}
86+
87+
@inline(never)
88+
public func run_SequenceAlgosArray(_ N: Int) {
89+
for _ in 0..<N {
90+
benchmarkSequenceAlgos(s: a, n: a.count)
91+
benchmarkEquatableSequenceAlgos(s: a, n: a.count)
92+
}
93+
}
94+
95+
@inline(never)
96+
public func run_SequenceAlgosContiguousArray(_ N: Int) {
97+
for _ in 0..<N {
98+
benchmarkSequenceAlgos(s: c, n: c.count)
99+
benchmarkEquatableSequenceAlgos(s: c, n: c.count)
100+
}
101+
}
102+
103+
@inline(never)
104+
public func run_SequenceAlgosAnySequence(_ N: Int) {
105+
for _ in 0..<N {
106+
benchmarkSequenceAlgos(s: y, n: n)
107+
}
108+
}
109+
110+
@inline(never)
111+
public func run_SequenceAlgosUnfoldSequence(_ N: Int) {
112+
for _ in 0..<N {
113+
benchmarkSequenceAlgos(s: s, n: n)
114+
}
115+
}
116+
117+
@inline(never)
118+
public func run_SequenceAlgosList(_ N: Int) {
119+
for _ in 0..<N {
120+
benchmarkSequenceAlgos(s: l, n: n)
121+
benchmarkEquatableSequenceAlgos(s: l, n: n)
122+
}
123+
}
124+
125+
enum List<Element> {
126+
case end
127+
indirect case node(Element, List<Element>)
128+
129+
init<S: BidirectionalCollection>(_ elements: S) where S.Element == Element {
130+
self = elements.reversed().reduce(.end) { .node($1,$0) }
131+
}
132+
}
133+

benchmark/utils/main.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ import RecursiveOwnedParameter
112112
import ReduceInto
113113
import ReversedCollections
114114
import RomanNumbers
115+
import SequenceAlgos
115116
import SetTests
116117
import SevenBoom
117118
import Sim2DArray
@@ -257,6 +258,7 @@ registerBenchmark(RecursiveOwnedParameter)
257258
registerBenchmark(ReduceInto)
258259
registerBenchmark(ReversedCollections)
259260
registerBenchmark(RomanNumbers)
261+
registerBenchmark(SequenceAlgos)
260262
registerBenchmark(SetTests)
261263
registerBenchmark(SevenBoom)
262264
registerBenchmark(Sim2DArray)

0 commit comments

Comments
 (0)