Skip to content

Commit 60e12f1

Browse files
committed
Add a benchmark for protocol conformance testing.
1 parent 21b91cd commit 60e12f1

File tree

3 files changed

+79
-0
lines changed

3 files changed

+79
-0
lines changed

benchmark/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ set(SWIFT_BENCH_MODULES
136136
single-source/PrefixWhile
137137
single-source/Prims
138138
single-source/PrimsNonStrongRef
139+
single-source/ProtocolConformance
139140
single-source/ProtocolDispatch
140141
single-source/ProtocolDispatch2
141142
single-source/Queue
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
//===--- ProtocolDispatch.swift -------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2020 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+
import TestsUtils
14+
15+
public let ProtocolConformance = BenchmarkInfo (
16+
name: "ProtocolConformance",
17+
runFunction: run_ProtocolConformance,
18+
tags: [.validation, .runtime])
19+
20+
protocol P {}
21+
22+
struct One: P {}
23+
struct Two {}
24+
25+
struct Cat<T, U> {}
26+
27+
extension Cat: P where T: P, U: P {}
28+
29+
protocol Growable {}
30+
extension Growable {
31+
func grow() -> (Growable, Growable) {
32+
return (Cat<Self, One>(), Cat<Self, Two>())
33+
}
34+
}
35+
36+
extension One: Growable {}
37+
extension Two: Growable {}
38+
extension Cat: Growable {}
39+
40+
@inline(never)
41+
public func run_ProtocolConformance(_ N: Int) {
42+
var array: [Growable] = [One(), Two()]
43+
var i = 0
44+
var checks = 0
45+
46+
// The expected number of times we expect `elt is P` to be true.
47+
var expectedConforms = 0
48+
49+
// The expected number of times we expect `elt is P` to be true
50+
// per iteration, at the current time.
51+
var expectedConformsPerIter = 1
52+
53+
// The number of times we've actually seen `elt is P` be true.
54+
var conforms = 0
55+
while checks < N * 500 {
56+
let (a, b) = array[i].grow()
57+
array.append(a)
58+
array.append(b)
59+
60+
// The number of times `elt is P` is true per outer iteration
61+
// goes up by 1 when the array's count is a power of 2.
62+
if array.count & (array.count - 1) == 0 {
63+
expectedConformsPerIter += 1
64+
}
65+
expectedConforms += expectedConformsPerIter
66+
67+
for elt in array {
68+
if elt is P {
69+
conforms += 1
70+
}
71+
checks += 1
72+
}
73+
i += 1
74+
}
75+
CheckResults(expectedConforms == conforms)
76+
}

benchmark/utils/main.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ import PrefixWhile
131131
import Prims
132132
import PrimsNonStrongRef
133133
import PrimsSplit
134+
import ProtocolConformance
134135
import ProtocolDispatch
135136
import ProtocolDispatch2
136137
import Queue
@@ -317,6 +318,7 @@ registerBenchmark(PrefixWhile)
317318
registerBenchmark(Prims)
318319
registerBenchmark(PrimsNonStrongRef)
319320
registerBenchmark(PrimsSplit)
321+
registerBenchmark(ProtocolConformance)
320322
registerBenchmark(ProtocolDispatch)
321323
registerBenchmark(ProtocolDispatch2)
322324
registerBenchmark(QueueGeneric)

0 commit comments

Comments
 (0)