|
| 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