@@ -66,6 +66,12 @@ public let benchmarks = [
66
66
tags: [ . validation, . api] ,
67
67
setUpFunction: setupKeyPathNestedStructs
68
68
) ,
69
+ BenchmarkInfo (
70
+ name: " KeyPathClassStructs " ,
71
+ runFunction: run_KeyPathClassStructs,
72
+ tags: [ . validation, . api] ,
73
+ setUpFunction: setupKeyPathNestedStructs
74
+ ) ,
69
75
]
70
76
71
77
/**
@@ -97,6 +103,7 @@ class FixedSizeArrayHolder {
97
103
var fixedSizeArray100 : FixedSizeArray100 < ElementType >
98
104
var fixedSizeArray10 : FixedSizeArray10 < ElementType >
99
105
var mainArrayForNestedStructs : [ A ]
106
+ var mainArrayForClassStructs : [ D1 ]
100
107
var arrayForMutatingGetset : [ MutatingGetsetNested1 ]
101
108
var arrayForGet : [ GetNested1 ]
102
109
var arrayForOptionals : [ Optional1 ]
@@ -107,6 +114,7 @@ class FixedSizeArrayHolder {
107
114
var keypathForOptional : KeyPath < Optional1 , Int ? >
108
115
var keypathForNestedClasses : KeyPath < C1 , Int >
109
116
var keypathForNonMutatingGetset : WritableKeyPath < M , Int >
117
+ var keypathForClassStructs : WritableKeyPath < D1 , Int >
110
118
111
119
// Same order as in KeyPathWritePerformance
112
120
var kp46 : WritableKeyPath < FixedSizeArray100 < ElementType > , ElementType >
@@ -176,6 +184,7 @@ class FixedSizeArrayHolder {
176
184
fixedSizeArray100 = initializeFixedSizeArray100 ( )
177
185
fixedSizeArray10 = initializeFixedSizeArray10 ( )
178
186
mainArrayForNestedStructs = [ A] ( )
187
+ mainArrayForClassStructs = [ D1] ( )
179
188
arrayForMutatingGetset = [ MutatingGetsetNested1] ( )
180
189
arrayForGet = [ GetNested1] ( )
181
190
arrayForOptionals = [ Optional1] ( )
@@ -252,6 +261,7 @@ class FixedSizeArrayHolder {
252
261
. _nestedItemStorage?! . _nestedItemStorage?! . _storage)
253
262
keypathForNestedClasses = identity ( \C1 . r. r. r. r. a)
254
263
keypathForNonMutatingGetset = identity ( \M . n. o. p. q. q)
264
+ keypathForClassStructs = identity ( \D1 . b. c. d. e. e)
255
265
}
256
266
}
257
267
@@ -262,6 +272,10 @@ public func setupKeyPathNestedStructs() {
262
272
let instance = A ( a: 0 , b: B ( b: 0 , c: C ( c: 0 , d: D ( d: 0 , e: E ( e: expectedIntForNestedItems) ) ) ) )
263
273
holder. mainArrayForNestedStructs. append ( instance)
264
274
275
+ let classStructInstance = D1 ( b: D2 ( b: 0 , c: D3 ( c: 0 , d: D4 ( d: 0 ,
276
+ e: D5 ( e: expectedIntForNestedItems) ) ) ) )
277
+ holder. mainArrayForClassStructs. append ( classStructInstance)
278
+
265
279
var mutatingGetsetInstance = MutatingGetsetNested1 ( )
266
280
mutatingGetsetInstance. nestedItem. nestedItem. nestedItem. nestedItem
267
281
. storage = expectedIntForNestedItems
@@ -333,6 +347,36 @@ struct E {
333
347
var e : Int
334
348
}
335
349
350
+ // Used for run_KeyPathClassStruct().
351
+ class D1 {
352
+ var a : Int
353
+ var b : D2
354
+ init ( b: D2 )
355
+ {
356
+ a = 0
357
+ self . b = b
358
+ }
359
+ }
360
+
361
+ struct D2 {
362
+ var b : Int
363
+ var c : D3
364
+ }
365
+
366
+ struct D3 {
367
+ var c : Int
368
+ var d : D4
369
+ }
370
+
371
+ struct D4 {
372
+ var d : Int
373
+ var e : D5
374
+ }
375
+
376
+ struct D5 {
377
+ var e : Int
378
+ }
379
+
336
380
// Used for run_KeyPathNestedClasses()
337
381
class C1 {
338
382
let a : Int = 0
@@ -1326,6 +1370,36 @@ public func run_KeyPathNestedStructs(n: Int) {
1326
1370
check ( sum == iterationMultipier * n * expectedIntForNestedItems)
1327
1371
}
1328
1372
1373
+ // This measures the performance of keypath reads where a block of
1374
+ // trivially-typed memory is preceded by something else (optionals, reference
1375
+ // types, etc.)
1376
+ @inline ( never)
1377
+ public func run_KeyPathClassStructs( n: Int ) {
1378
+ var sum = 0
1379
+ var index = 0
1380
+ let iterationMultipier = 500
1381
+
1382
+ let singleHopKeyPath0 : WritableKeyPath < D1 , D2 > = \D1 . b
1383
+ let singleHopKeyPath1 : WritableKeyPath < D2 , D3 > = \D2 . c
1384
+ let singleHopKeyPath2 : WritableKeyPath < D3 , D4 > = \D3 . d
1385
+ let singleHopKeyPath3 : WritableKeyPath < D4 , D5 > = \D4 . e
1386
+ let singleHopKeyPath4 : WritableKeyPath < D5 , Int > = \D5 . e
1387
+
1388
+ let appendedKeyPath = identity ( singleHopKeyPath0. appending ( path: singleHopKeyPath1)
1389
+ . appending ( path: singleHopKeyPath2) . appending ( path: singleHopKeyPath3)
1390
+ . appending ( path: singleHopKeyPath4) )
1391
+
1392
+ let elementCount = FixedSizeArrayHolder . shared. mainArrayForClassStructs. count
1393
+ for _ in 1 ... iterationMultipier * n {
1394
+ let element = FixedSizeArrayHolder . shared. mainArrayForClassStructs [ index]
1395
+ sum += element [ keyPath: appendedKeyPath]
1396
+ index = ( index + 1 ) % elementCount
1397
+ }
1398
+ check ( sum == iterationMultipier * n * expectedIntForNestedItems)
1399
+ }
1400
+
1401
+
1402
+
1329
1403
// This is meant as a baseline, from a timing perspective,
1330
1404
// for run_testKeyPathReadPerformance() and run_testKeyPathWritePerformance().
1331
1405
// It's currently set to ".skip", but is useful for comparing the performance between keypath operations and direct dot-notation.
0 commit comments