Skip to content

Commit 1bd702a

Browse files
committed
[benchmark] GYB ExistentialPerformance
Painstakingly reverse-engineered the boilerplate generator, that produces ExistentialPerformance.swift (sans few whitespace differences), to ease maintanance (The upcoming refactoring).
1 parent ae4ecbe commit 1bd702a

File tree

2 files changed

+259
-9
lines changed

2 files changed

+259
-9
lines changed

benchmark/single-source/ExistentialPerformance.swift

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===----------------------------------------------------------------------===//
1+
//===--- ExistentialPerformance.swift -------------------------*- swift -*-===//
22
//
33
// This source file is part of the Swift.org open source project
44
//
@@ -10,6 +10,12 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
////////////////////////////////////////////////////////////////////////////////
14+
// WARNING: This file is manually generated from .gyb template and should not
15+
// be directly modified. Instead, change ExistentialPerformance.swift.gyb
16+
// and run scripts/generate_harness/generate_harness.py to regenerate this file.
17+
////////////////////////////////////////////////////////////////////////////////
18+
1319
import TestsUtils
1420

1521
public let ExistentialPerformance = [
@@ -144,10 +150,10 @@ struct IntValueBuffer1 : Existential {
144150
return f0 == 0
145151
}
146152
func reallyDoIt() -> Bool {
147-
return true
153+
return true
148154
}
149155
mutating func mutateIt() -> Bool {
150-
next(&f0, upto: 1)
156+
next(&f0, upto: 1)
151157
return true
152158
}
153159
}
@@ -180,8 +186,7 @@ struct IntValueBuffer3 : Existential {
180186
func reallyDoIt() -> Bool {
181187
return f0 == 0 && f1 == 3 && f2 == 7
182188
}
183-
184-
mutating func mutateIt() -> Bool{
189+
mutating func mutateIt() -> Bool {
185190
next(&f0, upto: 1)
186191
next(&f1, upto: 3)
187192
next(&f2, upto: 7)
@@ -201,8 +206,7 @@ struct IntValueBuffer4 : Existential {
201206
func reallyDoIt() -> Bool {
202207
return f0 == 0 && f1 == 3 && f2 == 7 && f3 == 13
203208
}
204-
205-
mutating func mutateIt() -> Bool{
209+
mutating func mutateIt() -> Bool {
206210
next(&f0, upto: 1)
207211
next(&f1, upto: 3)
208212
next(&f2, upto: 7)
@@ -281,12 +285,11 @@ struct ClassValueBuffer4 : Existential {
281285
var f0: Klazz = Klazz()
282286
var f1: Klazz = Klazz()
283287
var f2: Klazz = Klazz()
284-
var f3: Int = 0
288+
var f3: Int = 0
285289

286290
func doIt() -> Bool {
287291
return f0.doIt()
288292
}
289-
290293
func reallyDoIt() -> Bool {
291294
return f0.reallyDoIt()
292295
}
@@ -415,6 +418,7 @@ func runTestArrayShift<T: Existential>(withType: T.Type, numberOfTimes N: Int) {
415418
}
416419
}
417420
}
421+
418422
func runTestArrayConditionalShift<T: Existential>(withType: T.Type, numberOfTimes N: Int) {
419423
var existentialArray = initExistentialArray(withType: T.self, count: 128)
420424
for _ in 0 ..< N * 10 {
@@ -746,3 +750,7 @@ public func run_ExistentialTestArrayConditionalShift_ClassValueBuffer3(_ N: Int)
746750
public func run_ExistentialTestArrayConditionalShift_ClassValueBuffer4(_ N: Int) {
747751
runTestArrayConditionalShift(withType: ClassValueBuffer4.self, numberOfTimes: N)
748752
}
753+
754+
// Local Variables:
755+
// eval: (read-only-mode 1)
756+
// End:
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
//===--- ExistentialPerformance.swift -------------------------*- 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+
% # Ignore the following warning. This _is_ the correct file to edit.
14+
////////////////////////////////////////////////////////////////////////////////
15+
// WARNING: This file is manually generated from .gyb template and should not
16+
// be directly modified. Instead, change ExistentialPerformance.swift.gyb
17+
// and run scripts/generate_harness/generate_harness.py to regenerate this file.
18+
////////////////////////////////////////////////////////////////////////////////
19+
20+
import TestsUtils
21+
22+
%{
23+
FN = 'ExistentialTest'
24+
Groups = (
25+
['Array' + g for g in ['ConditionalShift', 'Mutating', 'OneMethodCall',
26+
'Shift', 'TwoMethodCalls']] +
27+
['MutatingAndNonMutating', 'Mutating', 'OneMethodCall',
28+
'PassExistentialOneMethodCall', 'PassExistentialTwoMethodCalls',
29+
'TwoMethodCalls']
30+
)
31+
Vars = [(0, 0), (1, 3), (2, 7), (3, 13)]
32+
Refs = ['ClassValueBuffer' + str(i) for i in range(1, 5)]
33+
Vals = ['IntValueBuffer' + str(i) for i in range(0, 5)]
34+
Variants = Refs + Vals
35+
Names = [FN + group + '_' + variant for group in Groups for variant in Variants]
36+
37+
Setup = """
38+
let existentialArray = initExistentialArray(withType: T.self, count: 128)
39+
let existential = initExistential(withType: T.self)
40+
let existential2 = initExistential(withType: T.self)
41+
var existential = initExistential(withType: T.self)
42+
var existentialArray = initExistentialArray(withType: T.self, count: 128)
43+
""".splitlines()[1:]
44+
Setup = [Setup[0], Setup[1], '\n'.join(Setup[1:3]), Setup[3], Setup[4]]
45+
46+
Workloads = [
47+
('OneMethodCall', Setup[1], '20_000', """
48+
if !existential.doIt() {
49+
fatalError("expected true")
50+
}
51+
"""),
52+
('TwoMethodCalls', Setup[1], '20_000', """
53+
if !existential.doIt() || !existential.reallyDoIt() {
54+
fatalError("expected true")
55+
}
56+
"""),
57+
('PassExistentialOneMethodCall', Setup[2], '20_000', """
58+
if !passExistentialTwiceOneMethodCall(existential, existential2) {
59+
fatalError("expected true")
60+
}
61+
"""),
62+
('PassExistentialTwoMethodCalls', Setup[2], '20_000', """
63+
if !passExistentialTwiceTwoMethodCalls(existential, existential2) {
64+
fatalError("expected true")
65+
}
66+
"""),
67+
('Mutating', Setup[3], '10_000', """
68+
if !existential.mutateIt() {
69+
fatalError("expected true")
70+
}
71+
"""),
72+
('MutatingAndNonMutating', Setup[3], '10_000', """
73+
let _ = existential.doIt()
74+
if !existential.mutateIt() {
75+
fatalError("expected true")
76+
}
77+
"""),
78+
('ArrayOneMethodCall', Setup[0], '100', """
79+
for elt in existentialArray {
80+
if !elt.doIt() {
81+
fatalError("expected true")
82+
}
83+
}
84+
"""),
85+
('ArrayTwoMethodCalls', Setup[0], '100', """
86+
for elt in existentialArray {
87+
if !elt.doIt() || !elt.reallyDoIt() {
88+
fatalError("expected true")
89+
}
90+
}
91+
"""),
92+
('ArrayMutating', Setup[4], '100', """
93+
for i in 0 ..< existentialArray.count {
94+
if !existentialArray[i].mutateIt() {
95+
fatalError("expected true")
96+
}
97+
}
98+
"""),
99+
('ArrayShift', Setup[4], '10', """
100+
for i in 0 ..< existentialArray.count-1 {
101+
existentialArray.swapAt(i, i+1)
102+
}
103+
"""),
104+
('ArrayConditionalShift', Setup[4], '10', """
105+
for i in 0 ..< existentialArray.count-1 {
106+
let curr = existentialArray[i]
107+
if curr.doIt() {
108+
existentialArray[i] = existentialArray[i+1]
109+
existentialArray[i+1] = curr
110+
}
111+
}
112+
"""),
113+
]
114+
}%
115+
public let ExistentialPerformance = [
116+
% for Name in Names:
117+
BenchmarkInfo(name: "${Name}", runFunction: run_${Name}, tags: [.unstable${
118+
', .api, .Array' if 'Array' in Name else ''}]),
119+
% end
120+
]
121+
122+
protocol Existential {
123+
init()
124+
func doIt() -> Bool
125+
func reallyDoIt() -> Bool
126+
mutating func mutateIt() -> Bool
127+
}
128+
129+
struct IntValueBuffer0 : Existential {
130+
func doIt() -> Bool {
131+
return true
132+
}
133+
func reallyDoIt() -> Bool {
134+
return true
135+
}
136+
mutating func mutateIt() -> Bool {
137+
return true
138+
}
139+
}
140+
141+
func next(_ x: inout Int, upto mod: Int) {
142+
x = (x + 1) % (mod + 1)
143+
}
144+
145+
% for (V, i) in [(v, int(filter(str.isdigit, v))) for v in Vals[1:]]:
146+
struct ${V} : Existential {
147+
${'\n '.join(['var f{0}: Int = {1}'.format(vi, v)
148+
for (vi, v) in Vars[0:i]])}
149+
150+
func doIt() -> Bool {
151+
return f0 == 0
152+
}
153+
func reallyDoIt() -> Bool {
154+
return ${
155+
'true' if i == 1 else
156+
' && '.join(['f{0} == {1}'.format(vi, v) for (vi, v) in Vars[0:i]])}
157+
}
158+
mutating func mutateIt() -> Bool {
159+
${
160+
'\n '.join(['next(&f{0}, upto: {1})'.format(vi, (v if v > 0 else 1))
161+
for (vi, v) in Vars[0:i]])}
162+
return true
163+
}
164+
}
165+
166+
% end
167+
class Klazz {
168+
var f0: Int = 0
169+
var f1: Int = 3
170+
171+
func doIt() -> Bool {
172+
return f0 == 0
173+
}
174+
func reallyDoIt() -> Bool {
175+
return f0 == 0 && f1 == 3
176+
}
177+
178+
func mutateIt() -> Bool{
179+
next(&f0, upto: 1)
180+
next(&f1, upto: 3)
181+
return true
182+
}
183+
}
184+
185+
% for (V, i) in [(v, int(filter(str.isdigit, v))) for v in Refs]:
186+
struct ${V} : Existential {
187+
${'\n '.join([('var f{0}: Klazz = Klazz()'.format(vi) if vi < 3 else
188+
'var f3: Int = 0') for (vi, _) in Vars[0:i]])}
189+
190+
func doIt() -> Bool {
191+
return f0.doIt()
192+
}
193+
func reallyDoIt() -> Bool {
194+
return f0.reallyDoIt()
195+
}
196+
197+
mutating func mutateIt() -> Bool{
198+
return f0.mutateIt()
199+
}
200+
}
201+
202+
% end
203+
204+
@inline(never)
205+
func initExistential<T: Existential>(withType: T.Type) -> Existential {
206+
return T()
207+
}
208+
209+
@inline(never)
210+
func initExistentialArray<T: Existential>(withType: T.Type, count c: Int) -> [Existential] {
211+
return [T](repeating: T(), count: c)
212+
}
213+
214+
@inline(never)
215+
func passExistentialTwiceOneMethodCall(_ e0: Existential, _ e1: Existential) -> Bool {
216+
return e0.doIt() && e1.doIt()
217+
}
218+
219+
@inline(never)
220+
func passExistentialTwiceTwoMethodCalls(_ e0: Existential, _ e1: Existential) -> Bool {
221+
return e0.doIt() && e1.doIt() && e0.reallyDoIt() && e1.reallyDoIt()
222+
}
223+
% for (name, setup, multiple, workload) in Workloads:
224+
${"""
225+
func runTest{0}<T: Existential>(withType: T.Type, numberOfTimes N: Int) {{
226+
{1}
227+
for _ in 0 ..< N * {2} {{{3} }}
228+
}}""".format(name, setup, multiple, workload)}
229+
% end
230+
231+
% for (Name, _, _, _) in Workloads:
232+
// Test${Name}.
233+
% for Variant in Vals + Refs:
234+
public func run_ExistentialTest${Name}_${Variant}(_ N: Int) {
235+
runTest${Name}(withType: ${Variant}.self, numberOfTimes: N)
236+
}
237+
% end
238+
239+
% end
240+
// ${'Local Variables'}:
241+
// eval: (read-only-mode 1)
242+
// End:

0 commit comments

Comments
 (0)