Skip to content

Commit 4ca08a5

Browse files
authored
Merge pull request #22673 from palimondo/a-tall-white-fountain-played
[benchmark] Janitor Duty: Sweep Quadratic
2 parents 5faa0ba + e13e90b commit 4ca08a5

File tree

5 files changed

+49
-100
lines changed

5 files changed

+49
-100
lines changed

benchmark/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ set(SWIFT_BENCH_MODULES
8989
single-source/FloatingPointPrinting
9090
single-source/Hanoi
9191
single-source/Hash
92-
single-source/HashQuadratic
9392
single-source/Histogram
9493
single-source/InsertCharacter
9594
single-source/Integrate

benchmark/single-source/DictionaryCopy.swift

Lines changed: 38 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -17,66 +17,54 @@
1717

1818
import TestsUtils
1919

20-
public let DictionaryCopy = [
21-
BenchmarkInfo(name: "DictionaryCopy", runFunction: run_DictionaryCopy,
22-
tags: [.validation, .api, .Dictionary]),
23-
BenchmarkInfo(name: "DictionaryFilter", runFunction: run_DictionaryFilter,
24-
tags: [.validation, .api, .Dictionary]),
25-
]
20+
let t: [BenchmarkCategory] = [.validation, .api, .Dictionary]
2621

27-
@inline(never)
28-
public func testCopy(_ size: Int) {
29-
var dict1 = [Int: Int](minimumCapacity: size)
22+
// We run the test at a spread of sizes between 1*x and 2*x, because the
23+
// quadratic behavior only happens at certain load factors.
3024

31-
// Fill dictionary
32-
for i in 1...size {
33-
dict1[i] = 2 * i
34-
}
35-
CheckResults(dict1.count == size)
25+
public let DictionaryCopy = [
26+
BenchmarkInfo(name:"Dict.CopyKeyValue.16k",
27+
runFunction: copyKeyValue, tags: t, setUpFunction: { dict(16_000) }),
28+
BenchmarkInfo(name:"Dict.CopyKeyValue.20k",
29+
runFunction: copyKeyValue, tags: t, setUpFunction: { dict(20_000) }),
30+
BenchmarkInfo(name:"Dict.CopyKeyValue.24k",
31+
runFunction: copyKeyValue, tags: t, setUpFunction: { dict(24_000) }),
32+
BenchmarkInfo(name:"Dict.CopyKeyValue.28k",
33+
runFunction: copyKeyValue, tags: t, setUpFunction: { dict(28_000) }),
3634

37-
var dict2 = [Int: Int]()
38-
for (key, value) in dict1 {
39-
dict2[key] = value
40-
}
41-
CheckResults(dict2.count == size)
42-
}
35+
BenchmarkInfo(name:"Dict.FilterAllMatch.16k",
36+
runFunction: filterAllMatch, tags: t, setUpFunction: { dict(16_000) }),
37+
BenchmarkInfo(name:"Dict.FilterAllMatch.20k",
38+
runFunction: filterAllMatch, tags: t, setUpFunction: { dict(20_000) }),
39+
BenchmarkInfo(name:"Dict.FilterAllMatch.24k",
40+
runFunction: filterAllMatch, tags: t, setUpFunction: { dict(24_000) }),
41+
BenchmarkInfo(name:"Dict.FilterAllMatch.28k",
42+
runFunction: filterAllMatch, tags: t, setUpFunction: { dict(28_000) }),
43+
]
4344

44-
@inline(never)
45-
public func run_DictionaryCopy(_ N: Int) {
46-
for _ in 0 ..< N {
47-
// We run the test at a spread of sizes between 1*x and 2*x, because the
48-
// quadratic behavior only happens at certain load factors.
49-
testCopy(100_000)
50-
testCopy(125_000)
51-
testCopy(150_000)
52-
testCopy(175_000)
53-
}
45+
var dict: [Int: Int]?
46+
47+
func dict(_ size: Int) {
48+
dict = Dictionary(uniqueKeysWithValues: zip(1...size, 1...size))
5449
}
5550

5651
@inline(never)
57-
public func testFilter(_ size: Int) {
58-
var dict1 = [Int: Int](minimumCapacity: size)
59-
60-
// Fill dictionary
61-
for i in 1...size {
62-
dict1[i] = 2 * i
52+
func copyKeyValue(N: Int) {
53+
for _ in 1...N {
54+
var copy = [Int: Int]()
55+
for (key, value) in dict! {
56+
copy[key] = value
57+
}
58+
CheckResults(copy.count == dict!.count)
6359
}
64-
CheckResults(dict1.count == size)
65-
66-
// Filter with a predicate returning true is essentially the same loop as the
67-
// one in testCopy above.
68-
let dict2 = dict1.filter { _ in true }
69-
CheckResults(dict2.count == size)
7060
}
7161

62+
// Filter with a predicate returning true is essentially the same loop as the
63+
// one in copyKeyValue above.
7264
@inline(never)
73-
public func run_DictionaryFilter(_ N: Int) {
74-
for _ in 0 ..< N {
75-
// We run the test at a spread of sizes between 1*x and 2*x, because the
76-
// quadratic behavior only happens at certain load factors.
77-
testFilter(100_000)
78-
testFilter(125_000)
79-
testFilter(150_000)
80-
testFilter(175_000)
65+
func filterAllMatch(N: Int) {
66+
for _ in 1...N {
67+
let copy = dict!.filter { _ in true }
68+
CheckResults(copy.count == dict!.count)
8169
}
8270
}

benchmark/single-source/HashQuadratic.swift

Lines changed: 0 additions & 37 deletions
This file was deleted.

benchmark/utils/main.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ import FlattenList
7777
import FloatingPointPrinting
7878
import Hanoi
7979
import Hash
80-
import HashQuadratic
8180
import Histogram
8281
import InsertCharacter
8382
import Integrate
@@ -249,7 +248,6 @@ registerBenchmark(FlattenListFlatMap)
249248
registerBenchmark(FloatingPointPrinting)
250249
registerBenchmark(Hanoi)
251250
registerBenchmark(HashTest)
252-
registerBenchmark(HashQuadratic)
253251
registerBenchmark(Histogram)
254252
registerBenchmark(InsertCharacter)
255253
registerBenchmark(IntegrateTest)

test/benchmark/Benchmark_O.test.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ as a verification of this public API to prevent its accidental breakage.
1414
[BD]: https://github.com/apple/swift/blob/master/benchmark/scripts/Benchmark_Driver
1515
[Testing]: https://github.com/apple/swift/blob/master/docs/Testing.md
1616

17-
Note: Following tests use *HashQuadratic* as an example of a benchmark that is
18-
excluded from the default "pre-commit" list because it is marked `unstable` and
19-
the default skip-tags (`unstable,skip`) will exclude it. The *Ackermann* and
17+
Note: Following tests use *Existential.* as an example of a benchmarks that are
18+
excluded from the default "pre-commit" list because they are marked `skip` and
19+
the default skip-tags (`unstable,skip`) will exclude them. The *Ackermann* and
2020
*AngryPhonebook* are alphabetically the first two benchmarks in the test suite
2121
(used to verify running by index). If these assumptions change, the test must be
2222
adapted.
@@ -27,22 +27,22 @@ RUN: %Benchmark_O --list | %FileCheck %s \
2727
RUN: --check-prefix LISTPRECOMMIT \
2828
RUN: --check-prefix LISTTAGS
2929
LISTPRECOMMIT: #,Test,[Tags]
30-
LISTPRECOMMIT-NOT: HashQuadratic
30+
LISTPRECOMMIT-NOT: Existential.
3131
LISTPRECOMMIT: {{[0-9]+}},AngryPhonebook
3232
LISTTAGS-SAME: ,[
3333
LISTTAGS-NOT: TestsUtils.BenchmarkCategory.
3434
LISTTAGS-SAME: String, api, validation
3535
LISTTAGS-SAME: ]
3636
````
3737

38-
Verify HashQuadratic is listed when skip-tags are explicitly empty and that it
39-
is marked unstable:
38+
Verify `Existential.` benchmarks are listed when skip-tags are explicitly empty
39+
and that they are marked `skip`:
4040

4141
````
4242
RUN: %Benchmark_O --list --skip-tags= | %FileCheck %s --check-prefix LISTALL
4343
LISTALL: AngryPhonebook
44-
LISTALL: HashQuadratic
45-
LISTALL-SAME: unstable
44+
LISTALL: Existential.
45+
LISTALL-SAME: skip
4646
````
4747

4848
## Benchmark Selection
@@ -54,8 +54,9 @@ It provides us with ability to do a "dry run".
5454
Run benchmark by name (even if its tags match the skip-tags) or test number:
5555

5656
````
57-
RUN: %Benchmark_O HashQuadratic --list | %FileCheck %s --check-prefix NAMEDSKIP
58-
NAMEDSKIP: HashQuadratic
57+
RUN: %Benchmark_O Existential.Mutating.Ref1 --list \
58+
RUN: | %FileCheck %s --check-prefix NAMEDSKIP
59+
NAMEDSKIP: Existential.Mutating.Ref1
5960
6061
RUN: %Benchmark_O 1 --list | %FileCheck %s --check-prefix RUNBYNUMBER
6162
RUNBYNUMBER: Ackermann

0 commit comments

Comments
 (0)