Skip to content

Commit 37e957f

Browse files
committed
[Capsule] Copy DictionaryBenchmark and add some Dictionary API
1 parent e8dbd8d commit 37e957f

File tree

5 files changed

+382
-5
lines changed

5 files changed

+382
-5
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,343 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift Collections open source project
4+
//
5+
// Copyright (c) 2021 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+
//
10+
//===----------------------------------------------------------------------===//
11+
12+
import CollectionsBenchmark
13+
import Capsule
14+
15+
extension Benchmark {
16+
public mutating func addCapsuleHashMapBenchmarks() {
17+
self.add(
18+
title: "HashMap<Int, Int> init(uniqueKeysWithValues:)",
19+
input: [Int].self
20+
) { input in
21+
let keysAndValues = input.map { ($0, 2 * $0) }
22+
return { timer in
23+
blackHole(HashMap(uniqueKeysWithValues: keysAndValues))
24+
}
25+
}
26+
27+
self.add(
28+
title: "HashMap<Int, Int> sequential iteration",
29+
input: [Int].self
30+
) { input in
31+
let d = HashMap(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
32+
return { timer in
33+
for item in d {
34+
blackHole(item)
35+
}
36+
}
37+
}
38+
39+
// self.add(
40+
// title: "HashMap<Int, Int>.Keys sequential iteration",
41+
// input: [Int].self
42+
// ) { input in
43+
// let d = HashMap(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
44+
// return { timer in
45+
// for item in d.keys {
46+
// blackHole(item)
47+
// }
48+
// }
49+
// }
50+
//
51+
// self.add(
52+
// title: "HashMap<Int, Int>.Values sequential iteration",
53+
// input: [Int].self
54+
// ) { input in
55+
// let d = HashMap(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
56+
// return { timer in
57+
// for item in d.values {
58+
// blackHole(item)
59+
// }
60+
// }
61+
// }
62+
63+
self.add(
64+
title: "HashMap<Int, Int> subscript, successful lookups",
65+
input: ([Int], [Int]).self
66+
) { input, lookups in
67+
let d = HashMap(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
68+
return { timer in
69+
for i in lookups {
70+
precondition(d[i] == 2 * i)
71+
}
72+
}
73+
}
74+
75+
self.add(
76+
title: "HashMap<Int, Int> subscript, unsuccessful lookups",
77+
input: ([Int], [Int]).self
78+
) { input, lookups in
79+
let d = HashMap(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
80+
let c = input.count
81+
return { timer in
82+
for i in lookups {
83+
precondition(d[i + c] == nil)
84+
}
85+
}
86+
}
87+
88+
self.add(
89+
title: "HashMap<Int, Int> subscript, noop setter",
90+
input: ([Int], [Int]).self
91+
) { input, lookups in
92+
return { timer in
93+
var d = HashMap(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
94+
let c = input.count
95+
timer.measure {
96+
for i in lookups {
97+
d[i + c] = nil
98+
}
99+
}
100+
precondition(d.count == input.count)
101+
blackHole(d)
102+
}
103+
}
104+
105+
self.add(
106+
title: "HashMap<Int, Int> subscript, set existing",
107+
input: ([Int], [Int]).self
108+
) { input, lookups in
109+
return { timer in
110+
var d = HashMap(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
111+
timer.measure {
112+
for i in lookups {
113+
d[i] = 0
114+
}
115+
}
116+
precondition(d.count == input.count)
117+
blackHole(d)
118+
}
119+
}
120+
121+
self.add(
122+
title: "HashMap<Int, Int> subscript, _modify",
123+
input: ([Int], [Int]).self
124+
) { input, lookups in
125+
return { timer in
126+
var d = HashMap(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
127+
timer.measure {
128+
for i in lookups {
129+
d[i]! *= 2
130+
}
131+
}
132+
precondition(d.count == input.count)
133+
blackHole(d)
134+
}
135+
}
136+
137+
self.addSimple(
138+
title: "HashMap<Int, Int> subscript, insert",
139+
input: [Int].self
140+
) { input in
141+
var d: [Int: Int] = [:]
142+
for i in input {
143+
d[i] = 2 * i
144+
}
145+
precondition(d.count == input.count)
146+
blackHole(d)
147+
}
148+
149+
self.addSimple(
150+
title: "HashMap<Int, Int> subscript, insert, reserving capacity",
151+
input: [Int].self
152+
) { input in
153+
var d: [Int: Int] = [:]
154+
d.reserveCapacity(input.count)
155+
for i in input {
156+
d[i] = 2 * i
157+
}
158+
precondition(d.count == input.count)
159+
blackHole(d)
160+
}
161+
162+
self.add(
163+
title: "HashMap<Int, Int> subscript, remove existing",
164+
input: ([Int], [Int]).self
165+
) { input, lookups in
166+
return { timer in
167+
var d = HashMap(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
168+
timer.measure {
169+
for i in lookups {
170+
d[i] = nil
171+
}
172+
}
173+
precondition(d.isEmpty)
174+
blackHole(d)
175+
}
176+
}
177+
178+
self.add(
179+
title: "HashMap<Int, Int> subscript, remove missing",
180+
input: ([Int], [Int]).self
181+
) { input, lookups in
182+
return { timer in
183+
var d = HashMap(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
184+
let c = input.count
185+
timer.measure {
186+
for i in lookups {
187+
d[i + c] = nil
188+
}
189+
}
190+
precondition(d.count == input.count)
191+
blackHole(d)
192+
}
193+
}
194+
195+
self.add(
196+
title: "HashMap<Int, Int> defaulted subscript, successful lookups",
197+
input: ([Int], [Int]).self
198+
) { input, lookups in
199+
let d = HashMap(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
200+
return { timer in
201+
for i in lookups {
202+
precondition(d[i, default: -1] != -1)
203+
}
204+
}
205+
}
206+
207+
self.add(
208+
title: "HashMap<Int, Int> defaulted subscript, unsuccessful lookups",
209+
input: ([Int], [Int]).self
210+
) { input, lookups in
211+
let d = HashMap(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
212+
return { timer in
213+
let c = d.count
214+
for i in lookups {
215+
precondition(d[i + c, default: -1] == -1)
216+
}
217+
}
218+
}
219+
220+
self.add(
221+
title: "HashMap<Int, Int> defaulted subscript, _modify existing",
222+
input: [Int].self
223+
) { input in
224+
return { timer in
225+
var d = HashMap(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
226+
timer.measure {
227+
for i in input {
228+
d[i, default: -1] *= 2
229+
}
230+
}
231+
precondition(d.count == input.count)
232+
blackHole(d)
233+
}
234+
}
235+
236+
self.add(
237+
title: "HashMap<Int, Int> defaulted subscript, _modify missing",
238+
input: ([Int], [Int]).self
239+
) { input, lookups in
240+
return { timer in
241+
var d = HashMap(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
242+
let c = input.count
243+
timer.measure {
244+
for i in lookups {
245+
d[c + i, default: -1] *= 2
246+
}
247+
}
248+
precondition(d.count == 2 * input.count)
249+
blackHole(d)
250+
}
251+
}
252+
253+
// self.add(
254+
// title: "HashMap<Int, Int> successful index(forKey:)",
255+
// input: ([Int], [Int]).self
256+
// ) { input, lookups in
257+
// let d = HashMap(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
258+
// return { timer in
259+
// for i in lookups {
260+
// precondition(d.index(forKey: i) != nil)
261+
// }
262+
// }
263+
// }
264+
//
265+
// self.add(
266+
// title: "HashMap<Int, Int> unsuccessful index(forKey:)",
267+
// input: ([Int], [Int]).self
268+
// ) { input, lookups in
269+
// let d = HashMap(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
270+
// return { timer in
271+
// for i in lookups {
272+
// precondition(d.index(forKey: lookups.count + i) == nil)
273+
// }
274+
// }
275+
// }
276+
277+
self.add(
278+
title: "HashMap<Int, Int> updateValue(_:forKey:), existing",
279+
input: ([Int], [Int]).self
280+
) { input, lookups in
281+
return { timer in
282+
var d = HashMap(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
283+
timer.measure {
284+
for i in lookups {
285+
d.updateValue(0, forKey: i)
286+
}
287+
}
288+
precondition(d.count == input.count)
289+
blackHole(d)
290+
}
291+
}
292+
293+
self.add(
294+
title: "HashMap<Int, Int> updateValue(_:forKey:), insert",
295+
input: ([Int], [Int]).self
296+
) { input, lookups in
297+
return { timer in
298+
var d = HashMap(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
299+
timer.measure {
300+
for i in lookups {
301+
d.updateValue(0, forKey: input.count + i)
302+
}
303+
}
304+
precondition(d.count == 2 * input.count)
305+
blackHole(d)
306+
}
307+
}
308+
309+
self.add(
310+
title: "HashMap<Int, Int> random removals (existing keys)",
311+
input: ([Int], [Int]).self
312+
) { input, lookups in
313+
return { timer in
314+
var d = HashMap(uniqueKeysWithValues: input.lazy.map { ($0, 2 * $0) })
315+
timer.measure {
316+
for i in lookups {
317+
precondition(d.removeValue(forKey: i) != nil)
318+
}
319+
}
320+
precondition(d.count == 0)
321+
blackHole(d)
322+
}
323+
}
324+
325+
self.add(
326+
title: "HashMap<Int, Int> random removals (missing keys)",
327+
input: ([Int], [Int]).self
328+
) { input, lookups in
329+
return { timer in
330+
let c = input.count
331+
var d = HashMap(uniqueKeysWithValues: input.lazy.map { (c + $0, 2 * $0) })
332+
timer.measure {
333+
for i in lookups {
334+
precondition(d.removeValue(forKey: i) == nil)
335+
}
336+
}
337+
precondition(d.count == input.count)
338+
blackHole(d)
339+
}
340+
}
341+
342+
}
343+
}

Benchmarks/swift-collections-benchmark/main.swift

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ var benchmark = Benchmark(title: "Collection Benchmarks")
1616
benchmark.addArrayBenchmarks()
1717
benchmark.addSetBenchmarks()
1818
benchmark.addDictionaryBenchmarks()
19+
benchmark.addCapsuleHashMapBenchmarks()
1920
benchmark.addDequeBenchmarks()
2021
benchmark.addOrderedSetBenchmarks()
2122
benchmark.addOrderedDictionaryBenchmarks()

Package.swift

+2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ let package = Package(
5454
.library(name: "Collections", targets: ["Collections"]),
5555
.library(name: "DequeModule", targets: ["DequeModule"]),
5656
.library(name: "OrderedCollections", targets: ["OrderedCollections"]),
57+
.library(name: "Capsule", targets: ["Capsule"]),
5758
],
5859
dependencies: [
5960
// This is only used in the benchmark executable target.
@@ -65,6 +66,7 @@ let package = Package(
6566
dependencies: [
6667
"DequeModule",
6768
"OrderedCollections",
69+
"Capsule",
6870
],
6971
path: "Sources/Collections",
7072
exclude: ["CMakeLists.txt"],

0 commit comments

Comments
 (0)