Skip to content

Commit 2702633

Browse files
committed
[benchmark] Extract setup from Existential.Array
Existential.Array group had setup overhead caused by initialization of the existential array. Since this seems to be quite substatial and is dependant on the existential type, it makes sense to add Array.init benchmark group that will measure it explicitly. Array setup is extracted into 9 type-specific functions. The setup inside the `run_` functions now grabs that array, prepared in `setUpFunction`, excluding the initialization from the measurement. This helped with extracting setup overhead from most cases, but it appears that the mutable test still have measurable overhead because they perform COW. I’ve tried to work around this by transfering ownership of the pre-initialized array with the `grabArray` function, but nilling the IUO was crashing at runtime. This should be fixed later.
1 parent 06cf0c8 commit 2702633

File tree

2 files changed

+157
-60
lines changed

2 files changed

+157
-60
lines changed

benchmark/single-source/ExistentialPerformance.swift

Lines changed: 122 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -75,53 +75,89 @@ public let ExistentialPerformance: [BenchmarkInfo] = [
7575
BenchmarkInfo(name: "Existential.MutatingAndNonMutating.Val2", runFunction: run_MutatingAndNonMutatingVal2, tags: t),
7676
BenchmarkInfo(name: "Existential.MutatingAndNonMutating.Val3", runFunction: run_MutatingAndNonMutatingVal3, tags: t),
7777
BenchmarkInfo(name: "Existential.MutatingAndNonMutating.Val4", runFunction: run_MutatingAndNonMutatingVal4, tags: t),
78-
BenchmarkInfo(name: "Existential.Array.method.1x.Ref1", runFunction: run_Array_method1xRef1, tags: ta),
79-
BenchmarkInfo(name: "Existential.Array.method.1x.Ref2", runFunction: run_Array_method1xRef2, tags: ta),
80-
BenchmarkInfo(name: "Existential.Array.method.1x.Ref3", runFunction: run_Array_method1xRef3, tags: ta),
81-
BenchmarkInfo(name: "Existential.Array.method.1x.Ref4", runFunction: run_Array_method1xRef4, tags: ta),
82-
BenchmarkInfo(name: "Existential.Array.method.1x.Val0", runFunction: run_Array_method1xVal0, tags: ta),
83-
BenchmarkInfo(name: "Existential.Array.method.1x.Val1", runFunction: run_Array_method1xVal1, tags: ta),
84-
BenchmarkInfo(name: "Existential.Array.method.1x.Val2", runFunction: run_Array_method1xVal2, tags: ta),
85-
BenchmarkInfo(name: "Existential.Array.method.1x.Val3", runFunction: run_Array_method1xVal3, tags: ta),
86-
BenchmarkInfo(name: "Existential.Array.method.1x.Val4", runFunction: run_Array_method1xVal4, tags: ta),
87-
BenchmarkInfo(name: "Existential.Array.method.2x.Ref1", runFunction: run_Array_method2xRef1, tags: ta),
88-
BenchmarkInfo(name: "Existential.Array.method.2x.Ref2", runFunction: run_Array_method2xRef2, tags: ta),
89-
BenchmarkInfo(name: "Existential.Array.method.2x.Ref3", runFunction: run_Array_method2xRef3, tags: ta),
90-
BenchmarkInfo(name: "Existential.Array.method.2x.Ref4", runFunction: run_Array_method2xRef4, tags: ta),
91-
BenchmarkInfo(name: "Existential.Array.method.2x.Val0", runFunction: run_Array_method2xVal0, tags: ta),
92-
BenchmarkInfo(name: "Existential.Array.method.2x.Val1", runFunction: run_Array_method2xVal1, tags: ta),
93-
BenchmarkInfo(name: "Existential.Array.method.2x.Val2", runFunction: run_Array_method2xVal2, tags: ta),
94-
BenchmarkInfo(name: "Existential.Array.method.2x.Val3", runFunction: run_Array_method2xVal3, tags: ta),
95-
BenchmarkInfo(name: "Existential.Array.method.2x.Val4", runFunction: run_Array_method2xVal4, tags: ta),
96-
BenchmarkInfo(name: "Existential.Array.Mutating.Ref1", runFunction: run_ArrayMutatingRef1, tags: ta),
97-
BenchmarkInfo(name: "Existential.Array.Mutating.Ref2", runFunction: run_ArrayMutatingRef2, tags: ta),
98-
BenchmarkInfo(name: "Existential.Array.Mutating.Ref3", runFunction: run_ArrayMutatingRef3, tags: ta),
99-
BenchmarkInfo(name: "Existential.Array.Mutating.Ref4", runFunction: run_ArrayMutatingRef4, tags: ta),
100-
BenchmarkInfo(name: "Existential.Array.Mutating.Val0", runFunction: run_ArrayMutatingVal0, tags: ta),
101-
BenchmarkInfo(name: "Existential.Array.Mutating.Val1", runFunction: run_ArrayMutatingVal1, tags: ta),
102-
BenchmarkInfo(name: "Existential.Array.Mutating.Val2", runFunction: run_ArrayMutatingVal2, tags: ta),
103-
BenchmarkInfo(name: "Existential.Array.Mutating.Val3", runFunction: run_ArrayMutatingVal3, tags: ta),
104-
BenchmarkInfo(name: "Existential.Array.Mutating.Val4", runFunction: run_ArrayMutatingVal4, tags: ta),
105-
BenchmarkInfo(name: "Existential.Array.Shift.Ref1", runFunction: run_ArrayShiftRef1, tags: ta),
106-
BenchmarkInfo(name: "Existential.Array.Shift.Ref2", runFunction: run_ArrayShiftRef2, tags: ta),
107-
BenchmarkInfo(name: "Existential.Array.Shift.Ref3", runFunction: run_ArrayShiftRef3, tags: ta),
108-
BenchmarkInfo(name: "Existential.Array.Shift.Ref4", runFunction: run_ArrayShiftRef4, tags: ta),
109-
BenchmarkInfo(name: "Existential.Array.Shift.Val0", runFunction: run_ArrayShiftVal0, tags: ta),
110-
BenchmarkInfo(name: "Existential.Array.Shift.Val1", runFunction: run_ArrayShiftVal1, tags: ta),
111-
BenchmarkInfo(name: "Existential.Array.Shift.Val2", runFunction: run_ArrayShiftVal2, tags: ta),
112-
BenchmarkInfo(name: "Existential.Array.Shift.Val3", runFunction: run_ArrayShiftVal3, tags: ta),
113-
BenchmarkInfo(name: "Existential.Array.Shift.Val4", runFunction: run_ArrayShiftVal4, tags: ta),
114-
BenchmarkInfo(name: "Existential.Array.ConditionalShift.Ref1", runFunction: run_ArrayConditionalShiftRef1, tags: ta),
115-
BenchmarkInfo(name: "Existential.Array.ConditionalShift.Ref2", runFunction: run_ArrayConditionalShiftRef2, tags: ta),
116-
BenchmarkInfo(name: "Existential.Array.ConditionalShift.Ref3", runFunction: run_ArrayConditionalShiftRef3, tags: ta),
117-
BenchmarkInfo(name: "Existential.Array.ConditionalShift.Ref4", runFunction: run_ArrayConditionalShiftRef4, tags: ta),
118-
BenchmarkInfo(name: "Existential.Array.ConditionalShift.Val0", runFunction: run_ArrayConditionalShiftVal0, tags: ta),
119-
BenchmarkInfo(name: "Existential.Array.ConditionalShift.Val1", runFunction: run_ArrayConditionalShiftVal1, tags: ta),
120-
BenchmarkInfo(name: "Existential.Array.ConditionalShift.Val2", runFunction: run_ArrayConditionalShiftVal2, tags: ta),
121-
BenchmarkInfo(name: "Existential.Array.ConditionalShift.Val3", runFunction: run_ArrayConditionalShiftVal3, tags: ta),
122-
BenchmarkInfo(name: "Existential.Array.ConditionalShift.Val4", runFunction: run_ArrayConditionalShiftVal4, tags: ta),
78+
BenchmarkInfo(name: "Existential.Array.init.Ref1", runFunction: run_Array_initRef1, tags: ta, setUpFunction: caRef1),
79+
BenchmarkInfo(name: "Existential.Array.init.Ref2", runFunction: run_Array_initRef2, tags: ta, setUpFunction: caRef2),
80+
BenchmarkInfo(name: "Existential.Array.init.Ref3", runFunction: run_Array_initRef3, tags: ta, setUpFunction: caRef3),
81+
BenchmarkInfo(name: "Existential.Array.init.Ref4", runFunction: run_Array_initRef4, tags: ta, setUpFunction: caRef4),
82+
BenchmarkInfo(name: "Existential.Array.init.Val0", runFunction: run_Array_initVal0, tags: ta, setUpFunction: caVal0),
83+
BenchmarkInfo(name: "Existential.Array.init.Val1", runFunction: run_Array_initVal1, tags: ta, setUpFunction: caVal1),
84+
BenchmarkInfo(name: "Existential.Array.init.Val2", runFunction: run_Array_initVal2, tags: ta, setUpFunction: caVal2),
85+
BenchmarkInfo(name: "Existential.Array.init.Val3", runFunction: run_Array_initVal3, tags: ta, setUpFunction: caVal3),
86+
BenchmarkInfo(name: "Existential.Array.init.Val4", runFunction: run_Array_initVal4, tags: ta, setUpFunction: caVal4),
87+
BenchmarkInfo(name: "Existential.Array.method.1x.Ref1", runFunction: run_Array_method1xRef1, tags: ta, setUpFunction: caRef1),
88+
BenchmarkInfo(name: "Existential.Array.method.1x.Ref2", runFunction: run_Array_method1xRef2, tags: ta, setUpFunction: caRef2),
89+
BenchmarkInfo(name: "Existential.Array.method.1x.Ref3", runFunction: run_Array_method1xRef3, tags: ta, setUpFunction: caRef3),
90+
BenchmarkInfo(name: "Existential.Array.method.1x.Ref4", runFunction: run_Array_method1xRef4, tags: ta, setUpFunction: caRef4),
91+
BenchmarkInfo(name: "Existential.Array.method.1x.Val0", runFunction: run_Array_method1xVal0, tags: ta, setUpFunction: caVal0),
92+
BenchmarkInfo(name: "Existential.Array.method.1x.Val1", runFunction: run_Array_method1xVal1, tags: ta, setUpFunction: caVal1),
93+
BenchmarkInfo(name: "Existential.Array.method.1x.Val2", runFunction: run_Array_method1xVal2, tags: ta, setUpFunction: caVal2),
94+
BenchmarkInfo(name: "Existential.Array.method.1x.Val3", runFunction: run_Array_method1xVal3, tags: ta, setUpFunction: caVal3),
95+
BenchmarkInfo(name: "Existential.Array.method.1x.Val4", runFunction: run_Array_method1xVal4, tags: ta, setUpFunction: caVal4),
96+
BenchmarkInfo(name: "Existential.Array.method.2x.Ref1", runFunction: run_Array_method2xRef1, tags: ta, setUpFunction: caRef1),
97+
BenchmarkInfo(name: "Existential.Array.method.2x.Ref2", runFunction: run_Array_method2xRef2, tags: ta, setUpFunction: caRef2),
98+
BenchmarkInfo(name: "Existential.Array.method.2x.Ref3", runFunction: run_Array_method2xRef3, tags: ta, setUpFunction: caRef3),
99+
BenchmarkInfo(name: "Existential.Array.method.2x.Ref4", runFunction: run_Array_method2xRef4, tags: ta, setUpFunction: caRef4),
100+
BenchmarkInfo(name: "Existential.Array.method.2x.Val0", runFunction: run_Array_method2xVal0, tags: ta, setUpFunction: caVal0),
101+
BenchmarkInfo(name: "Existential.Array.method.2x.Val1", runFunction: run_Array_method2xVal1, tags: ta, setUpFunction: caVal1),
102+
BenchmarkInfo(name: "Existential.Array.method.2x.Val2", runFunction: run_Array_method2xVal2, tags: ta, setUpFunction: caVal2),
103+
BenchmarkInfo(name: "Existential.Array.method.2x.Val3", runFunction: run_Array_method2xVal3, tags: ta, setUpFunction: caVal3),
104+
BenchmarkInfo(name: "Existential.Array.method.2x.Val4", runFunction: run_Array_method2xVal4, tags: ta, setUpFunction: caVal4),
105+
BenchmarkInfo(name: "Existential.Array.Mutating.Ref1", runFunction: run_ArrayMutatingRef1, tags: ta, setUpFunction: caRef1),
106+
BenchmarkInfo(name: "Existential.Array.Mutating.Ref2", runFunction: run_ArrayMutatingRef2, tags: ta, setUpFunction: caRef2),
107+
BenchmarkInfo(name: "Existential.Array.Mutating.Ref3", runFunction: run_ArrayMutatingRef3, tags: ta, setUpFunction: caRef3),
108+
BenchmarkInfo(name: "Existential.Array.Mutating.Ref4", runFunction: run_ArrayMutatingRef4, tags: ta, setUpFunction: caRef4),
109+
BenchmarkInfo(name: "Existential.Array.Mutating.Val0", runFunction: run_ArrayMutatingVal0, tags: ta, setUpFunction: caVal0),
110+
BenchmarkInfo(name: "Existential.Array.Mutating.Val1", runFunction: run_ArrayMutatingVal1, tags: ta, setUpFunction: caVal1),
111+
BenchmarkInfo(name: "Existential.Array.Mutating.Val2", runFunction: run_ArrayMutatingVal2, tags: ta, setUpFunction: caVal2),
112+
BenchmarkInfo(name: "Existential.Array.Mutating.Val3", runFunction: run_ArrayMutatingVal3, tags: ta, setUpFunction: caVal3),
113+
BenchmarkInfo(name: "Existential.Array.Mutating.Val4", runFunction: run_ArrayMutatingVal4, tags: ta, setUpFunction: caVal4),
114+
BenchmarkInfo(name: "Existential.Array.Shift.Ref1", runFunction: run_ArrayShiftRef1, tags: ta, setUpFunction: caRef1),
115+
BenchmarkInfo(name: "Existential.Array.Shift.Ref2", runFunction: run_ArrayShiftRef2, tags: ta, setUpFunction: caRef2),
116+
BenchmarkInfo(name: "Existential.Array.Shift.Ref3", runFunction: run_ArrayShiftRef3, tags: ta, setUpFunction: caRef3),
117+
BenchmarkInfo(name: "Existential.Array.Shift.Ref4", runFunction: run_ArrayShiftRef4, tags: ta, setUpFunction: caRef4),
118+
BenchmarkInfo(name: "Existential.Array.Shift.Val0", runFunction: run_ArrayShiftVal0, tags: ta, setUpFunction: caVal0),
119+
BenchmarkInfo(name: "Existential.Array.Shift.Val1", runFunction: run_ArrayShiftVal1, tags: ta, setUpFunction: caVal1),
120+
BenchmarkInfo(name: "Existential.Array.Shift.Val2", runFunction: run_ArrayShiftVal2, tags: ta, setUpFunction: caVal2),
121+
BenchmarkInfo(name: "Existential.Array.Shift.Val3", runFunction: run_ArrayShiftVal3, tags: ta, setUpFunction: caVal3),
122+
BenchmarkInfo(name: "Existential.Array.Shift.Val4", runFunction: run_ArrayShiftVal4, tags: ta, setUpFunction: caVal4),
123+
BenchmarkInfo(name: "Existential.Array.ConditionalShift.Ref1", runFunction: run_ArrayConditionalShiftRef1, tags: ta, setUpFunction: caRef1),
124+
BenchmarkInfo(name: "Existential.Array.ConditionalShift.Ref2", runFunction: run_ArrayConditionalShiftRef2, tags: ta, setUpFunction: caRef2),
125+
BenchmarkInfo(name: "Existential.Array.ConditionalShift.Ref3", runFunction: run_ArrayConditionalShiftRef3, tags: ta, setUpFunction: caRef3),
126+
BenchmarkInfo(name: "Existential.Array.ConditionalShift.Ref4", runFunction: run_ArrayConditionalShiftRef4, tags: ta, setUpFunction: caRef4),
127+
BenchmarkInfo(name: "Existential.Array.ConditionalShift.Val0", runFunction: run_ArrayConditionalShiftVal0, tags: ta, setUpFunction: caVal0),
128+
BenchmarkInfo(name: "Existential.Array.ConditionalShift.Val1", runFunction: run_ArrayConditionalShiftVal1, tags: ta, setUpFunction: caVal1),
129+
BenchmarkInfo(name: "Existential.Array.ConditionalShift.Val2", runFunction: run_ArrayConditionalShiftVal2, tags: ta, setUpFunction: caVal2),
130+
BenchmarkInfo(name: "Existential.Array.ConditionalShift.Val3", runFunction: run_ArrayConditionalShiftVal3, tags: ta, setUpFunction: caVal3),
131+
BenchmarkInfo(name: "Existential.Array.ConditionalShift.Val4", runFunction: run_ArrayConditionalShiftVal4, tags: ta, setUpFunction: caVal4),
123132
]
124133

134+
// To exclude the setup overhead of existential array initialization,
135+
// these are setup functions that **create array** for each variant type.
136+
var array: [Existential]!
137+
func ca<T: Existential>(_: T.Type) {
138+
array = initExistentialArray(withType: T.self, count: 128)
139+
}
140+
func caVal0() { ca(Val0.self) }
141+
func caVal1() { ca(Val1.self) }
142+
func caVal2() { ca(Val2.self) }
143+
func caVal3() { ca(Val3.self) }
144+
func caVal4() { ca(Val4.self) }
145+
func caRef1() { ca(Ref1.self) }
146+
func caRef2() { ca(Ref2.self) }
147+
func caRef3() { ca(Ref3.self) }
148+
func caRef4() { ca(Ref4.self) }
149+
@inline(never)
150+
func grabArray() -> [Existential] { // transfer array ownership to caller
151+
// FIXME: This is causing Illegal Instruction: 4 crash
152+
// defer { array = nil }
153+
// return array
154+
// This doesn't work either:
155+
// let a = array!
156+
// array = nil
157+
// return a
158+
return array!
159+
}
160+
125161
protocol Existential {
126162
init()
127163
func doIt() -> Bool
@@ -374,8 +410,15 @@ func run_MutatingAndNonMutating<T: Existential>(withType: T.Type, numberOfTimes
374410
}
375411
}
376412

413+
func run_Array_init<T: Existential>(withType: T.Type, numberOfTimes N: Int) {
414+
415+
for _ in 0 ..< N * 20 {
416+
blackHole(initExistentialArray(withType: T.self, count: 128))
417+
}
418+
}
419+
377420
func run_Array_method1x<T: Existential>(withType: T.Type, numberOfTimes N: Int) {
378-
let existentialArray = initExistentialArray(withType: T.self, count: 128)
421+
let existentialArray = grabArray()
379422
for _ in 0 ..< N * 100 {
380423
for elt in existentialArray {
381424
if !elt.doIt() {
@@ -386,7 +429,7 @@ func run_Array_method1x<T: Existential>(withType: T.Type, numberOfTimes N: Int)
386429
}
387430

388431
func run_Array_method2x<T: Existential>(withType: T.Type, numberOfTimes N: Int) {
389-
let existentialArray = initExistentialArray(withType: T.self, count: 128)
432+
let existentialArray = grabArray()
390433
for _ in 0 ..< N * 100 {
391434
for elt in existentialArray {
392435
if !elt.doIt() || !elt.reallyDoIt() {
@@ -397,7 +440,7 @@ func run_Array_method2x<T: Existential>(withType: T.Type, numberOfTimes N: Int)
397440
}
398441

399442
func run_ArrayMutating<T: Existential>(withType: T.Type, numberOfTimes N: Int) {
400-
var existentialArray = initExistentialArray(withType: T.self, count: 128)
443+
var existentialArray = grabArray()
401444
for _ in 0 ..< N * 100 {
402445
for i in 0 ..< existentialArray.count {
403446
if !existentialArray[i].mutateIt() {
@@ -408,7 +451,7 @@ func run_ArrayMutating<T: Existential>(withType: T.Type, numberOfTimes N: Int) {
408451
}
409452

410453
func run_ArrayShift<T: Existential>(withType: T.Type, numberOfTimes N: Int) {
411-
var existentialArray = initExistentialArray(withType: T.self, count: 128)
454+
var existentialArray = grabArray()
412455
for _ in 0 ..< N * 10 {
413456
for i in 0 ..< existentialArray.count-1 {
414457
existentialArray.swapAt(i, i+1)
@@ -417,7 +460,7 @@ func run_ArrayShift<T: Existential>(withType: T.Type, numberOfTimes N: Int) {
417460
}
418461

419462
func run_ArrayConditionalShift<T: Existential>(withType: T.Type, numberOfTimes N: Int) {
420-
var existentialArray = initExistentialArray(withType: T.self, count: 128)
463+
var existentialArray = grabArray()
421464
for _ in 0 ..< N * 10 {
422465
for i in 0 ..< existentialArray.count-1 {
423466
let curr = existentialArray[i]
@@ -603,6 +646,35 @@ public func run_MutatingAndNonMutatingRef4(_ N: Int) {
603646
run_MutatingAndNonMutating(withType: Ref4.self, numberOfTimes: N)
604647
}
605648

649+
// Array.init.
650+
public func run_Array_initVal0(_ N: Int) {
651+
run_Array_init(withType: Val0.self, numberOfTimes: N)
652+
}
653+
public func run_Array_initVal1(_ N: Int) {
654+
run_Array_init(withType: Val1.self, numberOfTimes: N)
655+
}
656+
public func run_Array_initVal2(_ N: Int) {
657+
run_Array_init(withType: Val2.self, numberOfTimes: N)
658+
}
659+
public func run_Array_initVal3(_ N: Int) {
660+
run_Array_init(withType: Val3.self, numberOfTimes: N)
661+
}
662+
public func run_Array_initVal4(_ N: Int) {
663+
run_Array_init(withType: Val4.self, numberOfTimes: N)
664+
}
665+
public func run_Array_initRef1(_ N: Int) {
666+
run_Array_init(withType: Ref1.self, numberOfTimes: N)
667+
}
668+
public func run_Array_initRef2(_ N: Int) {
669+
run_Array_init(withType: Ref2.self, numberOfTimes: N)
670+
}
671+
public func run_Array_initRef3(_ N: Int) {
672+
run_Array_init(withType: Ref3.self, numberOfTimes: N)
673+
}
674+
public func run_Array_initRef4(_ N: Int) {
675+
run_Array_init(withType: Ref4.self, numberOfTimes: N)
676+
}
677+
606678
// Array.method.1x.
607679
public func run_Array_method1xVal0(_ N: Int) {
608680
run_Array_method1x(withType: Val0.self, numberOfTimes: N)

benchmark/single-source/ExistentialPerformance.swift.gyb

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ let t: [BenchmarkCategory] = []
2323
let ta: [BenchmarkCategory] = [.api, .Array]
2424
%{
2525
Setup = """
26-
let existentialArray = initExistentialArray(withType: T.self, count: 128)
2726
let existential = initExistential(withType: T.self)
2827
let existential2 = initExistential(withType: T.self)
2928
var existential = initExistential(withType: T.self)
30-
var existentialArray = initExistentialArray(withType: T.self, count: 128)
31-
""".splitlines()[1:]
32-
Setup = [Setup[0], Setup[1], '\n'.join(Setup[1:3]), Setup[3], Setup[4]]
29+
let existentialArray = grabArray()
30+
var existentialArray = grabArray()
31+
""".splitlines()
32+
Setup = [Setup[0], Setup[1], '\n'.join(Setup[1:3]), Setup[3], Setup[4], Setup[5]]
3333

3434
Workloads = [
3535
('method.1x', Setup[1], '20_000', """
@@ -63,33 +63,36 @@ Workloads = [
6363
fatalError("expected true")
6464
}
6565
"""),
66-
('Array.method.1x', Setup[0], '100', """
66+
('Array.init', Setup[0], '20', """
67+
blackHole(initExistentialArray(withType: T.self, count: 128))
68+
"""),
69+
('Array.method.1x', Setup[4], '100', """
6770
for elt in existentialArray {
6871
if !elt.doIt() {
6972
fatalError("expected true")
7073
}
7174
}
7275
"""),
73-
('Array.method.2x', Setup[0], '100', """
76+
('Array.method.2x', Setup[4], '100', """
7477
for elt in existentialArray {
7578
if !elt.doIt() || !elt.reallyDoIt() {
7679
fatalError("expected true")
7780
}
7881
}
7982
"""),
80-
('Array.Mutating', Setup[4], '100', """
83+
('Array.Mutating', Setup[5], '100', """
8184
for i in 0 ..< existentialArray.count {
8285
if !existentialArray[i].mutateIt() {
8386
fatalError("expected true")
8487
}
8588
}
8689
"""),
87-
('Array.Shift', Setup[4], '10', """
90+
('Array.Shift', Setup[5], '10', """
8891
for i in 0 ..< existentialArray.count-1 {
8992
existentialArray.swapAt(i, i+1)
9093
}
9194
"""),
92-
('Array.ConditionalShift', Setup[4], '10', """
95+
('Array.ConditionalShift', Setup[5], '10', """
9396
for i in 0 ..< existentialArray.count-1 {
9497
let curr = existentialArray[i]
9598
if curr.doIt() {
@@ -121,10 +124,32 @@ public let ExistentialPerformance: [BenchmarkInfo] = [
121124
% for Name in Names:
122125
BenchmarkInfo(name: "Existential.${Name}", runFunction: ${
123126
run_function_name(Name)}, tags: ${
124-
'ta' if 'Array' in Name else 't'}),
127+
'ta' if 'Array' in Name else 't'}${
128+
(', setUpFunction: ca' + Name.split('.')[-1]) if 'Array' in Name else '' }),
125129
% end
126130
]
127131

132+
// To exclude the setup overhead of existential array initialization,
133+
// these are setup functions that **create array** for each variant type.
134+
var array: [Existential]!
135+
func ca<T: Existential>(_: T.Type) {
136+
array = initExistentialArray(withType: T.self, count: 128)
137+
}
138+
% for Variant in Vals + Refs:
139+
func ca${Variant}() { ca(${Variant}.self) }
140+
% end
141+
@inline(never)
142+
func grabArray() -> [Existential] { // transfer array ownership to caller
143+
// FIXME: This is causing Illegal Instruction: 4 crash
144+
// defer { array = nil }
145+
// return array
146+
// This doesn't work either:
147+
// let a = array!
148+
// array = nil
149+
// return a
150+
return array!
151+
}
152+
128153
protocol Existential {
129154
init()
130155
func doIt() -> Bool

0 commit comments

Comments
 (0)