@@ -14,221 +14,68 @@ import Benchmark
14
14
import func Benchmark. blackHole
15
15
import FoundationEssentials
16
16
17
- struct Mace {
18
- let p1 : Int
19
- let p2 : Int
20
- let p3 : Int
21
- let p4 : Int
22
- let p5 : Int
23
- }
24
-
25
- struct Sword {
26
- let p1 : Int
27
- let p2 : Int
28
- let p3 : Int
29
- let p4 : Int
30
- let p5 : Int
31
- }
32
-
33
- struct Lightsaber {
34
- let p1 : Int
35
- let p2 : Int
36
- let p3 : Int
37
- let p4 : Int
38
- let p5 : Int
39
- }
40
-
41
- enum Weapon {
42
- case mace( Mace )
43
- case sword( Sword )
44
- case lightsaber( Lightsaber )
45
-
46
- var p1 : Int {
47
- switch self {
48
- case let . mace( mace) :
49
- mace. p1
50
- case let . sword( sword) :
51
- sword. p1
52
- case let . lightsaber( lighsaber) :
53
- lighsaber. p1
54
- }
55
- }
56
-
57
- var p2 : Int {
58
- switch self {
59
- case let . mace( mace) :
60
- mace. p2
61
- case let . sword( sword) :
62
- sword. p2
63
- case let . lightsaber( lighsaber) :
64
- lighsaber. p2
65
- }
66
- }
67
-
68
- var p3 : Int {
69
- switch self {
70
- case let . mace( mace) :
71
- mace. p3
72
- case let . sword( sword) :
73
- sword. p3
74
- case let . lightsaber( lighsaber) :
75
- lighsaber. p3
76
- }
77
- }
78
-
79
- var p4 : Int {
80
- switch self {
81
- case let . mace( mace) :
82
- mace. p4
83
- case let . sword( sword) :
84
- sword. p4
85
- case let . lightsaber( lighsaber) :
86
- lighsaber. p4
87
- }
88
- }
89
-
90
- var p5 : Int {
91
- switch self {
92
- case let . mace( mace) :
93
- mace. p5
94
- case let . sword( sword) :
95
- sword. p5
96
- case let . lightsaber( lighsaber) :
97
- lighsaber. p5
98
- }
99
- }
100
- }
101
-
102
- struct Monster {
103
- let name : String
104
- var level : Int
105
- var hp : Int
106
- var mana : Int
107
- var weapon : Weapon ?
108
- var levelComputed : Int { level }
109
- var weaponP1 : Int ? { weapon? . p1 }
110
- var weaponP2 : Int ? { weapon? . p2 }
111
- var weaponP3 : Int ? { weapon? . p3 }
112
- var weaponP4 : Int ? { weapon? . p4 }
113
- var weaponP5 : Int ? { weapon? . p5 }
114
- }
115
-
116
17
let benchmarks = {
117
18
Benchmark . defaultConfiguration. maxIterations = 1_000_000_000
118
19
Benchmark . defaultConfiguration. maxDuration = . seconds( 5 )
119
20
Benchmark . defaultConfiguration. scalingFactor = . kilo
21
+ Benchmark . defaultConfiguration. metrics = . arc + [ . cpuTotal, . wallClock, . mallocCountTotal, . throughput] // use ARC to see traffic
22
+ // Benchmark.defaultConfiguration.metrics = [.cpuTotal, .wallClock, .mallocCountTotal, .throughput] // skip ARC as it has some overhead
23
+ // Benchmark.defaultConfiguration.metrics = .all // Use all metrics to easily see which ones are of interest for this benchmark suite
120
24
121
25
if #available( macOS 14 , * ) {
122
- Benchmark ( " Predicate #1 - simple 'true' condition " ) { benchmark in
123
- let monster = Monster ( name: " Orc " , level: 80 , hp: 100 , mana: 0 , weapon: . sword( Sword ( p1: 1 , p2: 2 , p3: 3 , p4: 4 , p5: 5 ) ) )
124
- let predicate = #Predicate< Monster> { monster in
125
- true
126
- }
127
-
128
- benchmark. startMeasurement ( )
129
- var matched = 0
130
- for _ in benchmark. scaledIterations {
131
- if try predicate. evaluate ( monster) {
132
- matched += 1
26
+ let monster = Monster ( name: " Orc " , level: 80 , hp: 100 , mana: 0 , weapon: . sword( Sword ( p1: 1 , p2: 2 , p3: 3 , p4: 4 , p5: 5 ) ) )
27
+
28
+ var predicateTests : [ ( String , Predicate < Monster > ) ] = [ ]
29
+
30
+ predicateTests. append ( ( " Predicate #1 - simple 'true' condition " , #Predicate< Monster> { monster in
31
+ true
32
+ } ) )
33
+
34
+ predicateTests. append ( ( " Predicate #2 - 1 KeyPath variable condition " , #Predicate< Monster> { monster in
35
+ ( monster. level == 80 )
36
+ } ) )
37
+
38
+ predicateTests. append ( ( " Predicate #3 - 1 KeyPath computed property condition " , #Predicate< Monster> { monster in
39
+ ( monster. levelComputed == 80 )
40
+ } ) )
41
+
42
+ predicateTests. append ( ( " Predicate #4 - 1 KeyPath nested computed property condition " , #Predicate< Monster> { monster in
43
+ ( monster. weaponP1 == 1 )
44
+ } ) )
45
+
46
+ predicateTests. append ( ( " Predicate #5 - 3 KeyPath nested computed property conditions " , #Predicate< Monster> { monster in
47
+ ( ( monster. weaponP1 == 1 ) &&
48
+ ( monster. weaponP2 == 2 ) &&
49
+ ( monster. weaponP3 == 3 ) )
50
+ } ) )
51
+
52
+ // This test disabled, as enabling it will make compilation fail due to:
53
+ // .../swift-foundation/Benchmarks/Benchmarks/Predicates/Predicates.swift:17:5: error: the compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions
54
+ // let benchmarks = {
55
+ // ^~~~~~~~~~~~~~
56
+ // error: fatalError
57
+ // predicateTests.append(("Predicate #6 - 5 KeyPath nested computed property conditions", #Predicate<Monster> { monster in
58
+ // ((monster.weaponP1 == 1) &&
59
+ // (monster.weaponP2 == 2) &&
60
+ // (monster.weaponP3 == 3) &&
61
+ // (monster.weaponP4 == 4) &&
62
+ // (monster.weaponP5 == 5))
63
+ // }))
64
+
65
+ predicateTests. forEach { ( testDescription, predicate) in
66
+ Benchmark ( testDescription) { benchmark in
67
+ var matched = 0
68
+
69
+ for _ in benchmark. scaledIterations {
70
+ if try predicate. evaluate ( monster) {
71
+ matched += 1
72
+ }
133
73
}
134
- }
135
- benchmark. stopMeasurement ( )
136
-
137
- guard matched == benchmark. scaledIterations. count else {
138
- fatalError ( " Internal error: wrong number of matched monsters " )
139
- }
140
- }
141
- }
142
74
143
- if #available( macOS 14 , * ) {
144
- Benchmark ( " Predicate #2 - 1 KeyPath variable condition " ) { benchmark in
145
- let monster = Monster ( name: " Orc " , level: 80 , hp: 100 , mana: 0 , weapon: . sword( Sword ( p1: 1 , p2: 2 , p3: 3 , p4: 4 , p5: 5 ) ) )
146
- let predicate = #Predicate< Monster> { monster in
147
- ( monster. level == 80 )
148
- }
149
-
150
- benchmark. startMeasurement ( )
151
- var matched = 0
152
- for _ in benchmark. scaledIterations {
153
- if try predicate. evaluate ( monster) {
154
- matched += 1
75
+ guard matched == benchmark. scaledIterations. count else {
76
+ fatalError ( " Internal error: wrong number of matched monsters " )
155
77
}
156
78
}
157
- benchmark. stopMeasurement ( )
158
-
159
- guard matched == benchmark. scaledIterations. count else {
160
- fatalError ( " Internal error: wrong number of matched monsters " )
161
- }
162
- }
163
- }
164
-
165
- if #available( macOS 14 , * ) {
166
- Benchmark ( " Predicate #3 - 1 KeyPath computed property condition " ) { benchmark in
167
- let monster = Monster ( name: " Orc " , level: 80 , hp: 100 , mana: 0 , weapon: . sword( Sword ( p1: 1 , p2: 2 , p3: 3 , p4: 4 , p5: 5 ) ) )
168
- let predicate = #Predicate< Monster> { monster in
169
- ( monster. levelComputed == 80 )
170
- }
171
-
172
- benchmark. startMeasurement ( )
173
- var matched = 0
174
- for _ in benchmark. scaledIterations {
175
- if try predicate. evaluate ( monster) {
176
- matched += 1
177
- }
178
- }
179
- benchmark. stopMeasurement ( )
180
-
181
- guard matched == benchmark. scaledIterations. count else {
182
- fatalError ( " Internal error: wrong number of matched monsters " )
183
- }
184
- }
185
- }
186
-
187
- if #available( macOS 14 , * ) {
188
- Benchmark ( " Predicate #4 - 1 KeyPath nested computed property condition " ) { benchmark in
189
- let monster = Monster ( name: " Orc " , level: 80 , hp: 100 , mana: 0 , weapon: . sword( Sword ( p1: 1 , p2: 2 , p3: 3 , p4: 4 , p5: 5 ) ) )
190
- let predicate = #Predicate< Monster> { monster in
191
- ( monster. weaponP1 == 1 )
192
- }
193
-
194
- benchmark. startMeasurement ( )
195
- var matched = 0
196
- for _ in benchmark. scaledIterations {
197
- if try predicate. evaluate ( monster) {
198
- matched += 1
199
- }
200
- }
201
- benchmark. stopMeasurement ( )
202
-
203
- guard matched == benchmark. scaledIterations. count else {
204
- fatalError ( " Internal error: wrong number of matched monsters " )
205
- }
206
- }
207
- }
208
-
209
- if #available( macOS 14 , * ) {
210
- Benchmark ( " Predicate #5 - 3 KeyPath nested computed property conditions " ) { benchmark in
211
- let monster = Monster ( name: " Orc " , level: 80 , hp: 100 , mana: 0 , weapon: . sword( Sword ( p1: 1 , p2: 2 , p3: 3 , p4: 4 , p5: 5 ) ) )
212
- let predicate = #Predicate< Monster> { monster in
213
- ( ( monster. weaponP1 == 1 ) &&
214
- //(monster.weaponP2 == 2) &&
215
- //(monster.weaponP3 == 3) &&
216
- ( monster. weaponP4 == 4 ) &&
217
- ( monster. weaponP5 == 5 ) )
218
- }
219
-
220
- benchmark. startMeasurement ( )
221
- var matched = 0
222
- for _ in benchmark. scaledIterations {
223
- if try predicate. evaluate ( monster) {
224
- matched += 1
225
- }
226
- }
227
- benchmark. stopMeasurement ( )
228
-
229
- guard matched == benchmark. scaledIterations. count else {
230
- fatalError ( " Internal error: wrong number of matched monsters " )
231
- }
232
79
}
233
80
}
234
81
}
0 commit comments