Skip to content

Commit 51a5f26

Browse files
committed
[benchmark] CharacterProperties Legacy Factor
…plus an attempt at reducing wide range of memory used between independent, repeated measurements in the `CharacterPropertiesPrecomputed` benchmark by reserving the appropriate set capacity in advance.
1 parent e12dfe7 commit 51a5f26

File tree

2 files changed

+59
-31
lines changed

2 files changed

+59
-31
lines changed

benchmark/single-source/CharacterProperties.swift

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,29 @@ public let CharacterPropertiesFetch = BenchmarkInfo(
2323
name: "CharacterPropertiesFetch",
2424
runFunction: run_CharacterPropertiesFetch,
2525
tags: [.validation, .api, .String],
26-
setUpFunction: { blackHole(workload) })
26+
setUpFunction: { blackHole(workload) },
27+
legacyFactor: 10)
2728

2829
public let CharacterPropertiesStashed = BenchmarkInfo(
2930
name: "CharacterPropertiesStashed",
3031
runFunction: run_CharacterPropertiesStashed,
3132
tags: [.validation, .api, .String],
32-
setUpFunction: { setupStash() })
33+
setUpFunction: { setupStash() },
34+
legacyFactor: 10)
3335

3436
public let CharacterPropertiesStashedMemo = BenchmarkInfo(
3537
name: "CharacterPropertiesStashedMemo",
3638
runFunction: run_CharacterPropertiesStashedMemo,
3739
tags: [.validation, .api, .String],
38-
setUpFunction: { setupMemo() })
40+
setUpFunction: { setupMemo() },
41+
legacyFactor: 10)
3942

4043
public let CharacterPropertiesPrecomputed = BenchmarkInfo(
4144
name: "CharacterPropertiesPrecomputed",
4245
runFunction: run_CharacterPropertiesPrecomputed,
4346
tags: [.validation, .api, .String],
44-
setUpFunction: { setupPrecomputed() })
47+
setUpFunction: { setupPrecomputed() },
48+
legacyFactor: 10)
4549

4650
extension Character {
4751
var firstScalar: UnicodeScalar { return unicodeScalars.first! }
@@ -253,8 +257,8 @@ func setupMemo() {
253257
}
254258

255259
// Precompute whole scalar set
256-
func precompute(_ charSet: CharacterSet) -> Set<UInt32> {
257-
var result = Set<UInt32>()
260+
func precompute(_ charSet: CharacterSet, capacity: Int) -> Set<UInt32> {
261+
var result = Set<UInt32>(minimumCapacity: capacity)
258262
for plane in 0...0x10 {
259263
guard charSet.hasMember(inPlane: UInt8(plane)) else { continue }
260264
let offset = plane &* 0x1_0000
@@ -267,43 +271,53 @@ func precompute(_ charSet: CharacterSet) -> Set<UInt32> {
267271
}
268272
return result
269273
}
270-
var controlCharactersPrecomputed: Set<UInt32> = precompute(controlCharacters)
274+
var controlCharactersPrecomputed: Set<UInt32> =
275+
precompute(controlCharacters, capacity: 24951)
271276
func isControlPrecomputed(_ c: Character) -> Bool {
272277
return controlCharactersPrecomputed.contains(c.firstScalar.value)
273278
}
274-
var alphanumericsPrecomputed: Set<UInt32> = precompute(alphanumerics)
279+
var alphanumericsPrecomputed: Set<UInt32> =
280+
precompute(alphanumerics, capacity: 122647)
275281
func isAlphanumericPrecomputed(_ c: Character) -> Bool {
276282
return alphanumericsPrecomputed.contains(c.firstScalar.value)
277283
}
278-
var lowercaseLettersPrecomputed: Set<UInt32> = precompute(lowercaseLetters)
284+
var lowercaseLettersPrecomputed: Set<UInt32> =
285+
precompute(lowercaseLetters, capacity: 2063)
279286
func isLowercasePrecomputed(_ c: Character) -> Bool {
280287
return lowercaseLettersPrecomputed.contains(c.firstScalar.value)
281288
}
282-
var punctuationCharactersPrecomputed: Set<UInt32> = precompute(punctuationCharacters)
289+
var punctuationCharactersPrecomputed: Set<UInt32> =
290+
precompute(punctuationCharacters, capacity: 770)
283291
func isPunctuationPrecomputed(_ c: Character) -> Bool {
284292
return punctuationCharactersPrecomputed.contains(c.firstScalar.value)
285293
}
286-
var whitespacesPrecomputed: Set<UInt32> = precompute(whitespaces)
294+
var whitespacesPrecomputed: Set<UInt32> =
295+
precompute(whitespaces, capacity: 19)
287296
func isWhitespacePrecomputed(_ c: Character) -> Bool {
288297
return whitespacesPrecomputed.contains(c.firstScalar.value)
289298
}
290-
var lettersPrecomputed: Set<UInt32> = precompute(letters)
299+
var lettersPrecomputed: Set<UInt32> =
300+
precompute(letters, capacity: 121145)
291301
func isLetterPrecomputed(_ c: Character) -> Bool {
292302
return lettersPrecomputed.contains(c.firstScalar.value)
293303
}
294-
var uppercaseLettersPrecomputed: Set<UInt32> = precompute(uppercaseLetters)
304+
var uppercaseLettersPrecomputed: Set<UInt32> =
305+
precompute(uppercaseLetters, capacity: 1733)
295306
func isUppercasePrecomputed(_ c: Character) -> Bool {
296307
return uppercaseLettersPrecomputed.contains(c.firstScalar.value)
297308
}
298-
var decimalDigitsPrecomputed: Set<UInt32> = precompute(decimalDigits)
309+
var decimalDigitsPrecomputed: Set<UInt32> =
310+
precompute(decimalDigits, capacity: 590)
299311
func isDecimalPrecomputed(_ c: Character) -> Bool {
300312
return decimalDigitsPrecomputed.contains(c.firstScalar.value)
301313
}
302-
var newlinesPrecomputed: Set<UInt32> = precompute(newlines)
314+
var newlinesPrecomputed: Set<UInt32> =
315+
precompute(newlines, capacity: 7)
303316
func isNewlinePrecomputed(_ c: Character) -> Bool {
304317
return newlinesPrecomputed.contains(c.firstScalar.value)
305318
}
306-
var capitalizedLettersPrecomputed: Set<UInt32> = precompute(capitalizedLetters)
319+
var capitalizedLettersPrecomputed: Set<UInt32> =
320+
precompute(capitalizedLetters, capacity: 31)
307321
func isCapitalizedPrecomputed(_ c: Character) -> Bool {
308322
return capitalizedLettersPrecomputed.contains(c.firstScalar.value)
309323
}
@@ -345,7 +359,7 @@ let workload = """
345359

346360
@inline(never)
347361
public func run_CharacterPropertiesFetch(_ N: Int) {
348-
for _ in 1...N*10 {
362+
for _ in 1...N {
349363
for c in workload {
350364
blackHole(isControl(c))
351365
blackHole(isAlphanumeric(c))
@@ -363,7 +377,7 @@ public func run_CharacterPropertiesFetch(_ N: Int) {
363377

364378
@inline(never)
365379
public func run_CharacterPropertiesStashed(_ N: Int) {
366-
for _ in 1...N*10 {
380+
for _ in 1...N {
367381
for c in workload {
368382
blackHole(isControlStashed(c))
369383
blackHole(isAlphanumericStashed(c))
@@ -381,7 +395,7 @@ public func run_CharacterPropertiesStashed(_ N: Int) {
381395

382396
@inline(never)
383397
public func run_CharacterPropertiesStashedMemo(_ N: Int) {
384-
for _ in 1...N*10 {
398+
for _ in 1...N {
385399
for c in workload {
386400
blackHole(isControlStashedMemo(c))
387401
blackHole(isAlphanumericStashedMemo(c))
@@ -399,7 +413,7 @@ public func run_CharacterPropertiesStashedMemo(_ N: Int) {
399413

400414
@inline(never)
401415
public func run_CharacterPropertiesPrecomputed(_ N: Int) {
402-
for _ in 1...N*10 {
416+
for _ in 1...N {
403417
for c in workload {
404418
blackHole(isControlPrecomputed(c))
405419
blackHole(isAlphanumericPrecomputed(c))

benchmark/single-source/CharacterProperties.swift.gyb

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,25 +24,29 @@ public let CharacterPropertiesFetch = BenchmarkInfo(
2424
name: "CharacterPropertiesFetch",
2525
runFunction: run_CharacterPropertiesFetch,
2626
tags: [.validation, .api, .String],
27-
setUpFunction: { blackHole(workload) })
27+
setUpFunction: { blackHole(workload) },
28+
legacyFactor: 10)
2829

2930
public let CharacterPropertiesStashed = BenchmarkInfo(
3031
name: "CharacterPropertiesStashed",
3132
runFunction: run_CharacterPropertiesStashed,
3233
tags: [.validation, .api, .String],
33-
setUpFunction: { setupStash() })
34+
setUpFunction: { setupStash() },
35+
legacyFactor: 10)
3436

3537
public let CharacterPropertiesStashedMemo = BenchmarkInfo(
3638
name: "CharacterPropertiesStashedMemo",
3739
runFunction: run_CharacterPropertiesStashedMemo,
3840
tags: [.validation, .api, .String],
39-
setUpFunction: { setupMemo() })
41+
setUpFunction: { setupMemo() },
42+
legacyFactor: 10)
4043

4144
public let CharacterPropertiesPrecomputed = BenchmarkInfo(
4245
name: "CharacterPropertiesPrecomputed",
4346
runFunction: run_CharacterPropertiesPrecomputed,
4447
tags: [.validation, .api, .String],
45-
setUpFunction: { setupPrecomputed() })
48+
setUpFunction: { setupPrecomputed() },
49+
legacyFactor: 10)
4650

4751
extension Character {
4852
var firstScalar: UnicodeScalar { return unicodeScalars.first! }
@@ -104,8 +108,8 @@ func setupMemo() {
104108
}
105109

106110
// Precompute whole scalar set
107-
func precompute(_ charSet: CharacterSet) -> Set<UInt32> {
108-
var result = Set<UInt32>()
111+
func precompute(_ charSet: CharacterSet, capacity: Int) -> Set<UInt32> {
112+
var result = Set<UInt32>(minimumCapacity: capacity)
109113
for plane in 0...0x10 {
110114
guard charSet.hasMember(inPlane: UInt8(plane)) else { continue }
111115
let offset = plane &* 0x1_0000
@@ -118,8 +122,17 @@ func precompute(_ charSet: CharacterSet) -> Set<UInt32> {
118122
}
119123
return result
120124
}
125+
%{ #// Reduce wide memory range. Capacities from `print("${Set}:…` below.
126+
precomputed_capacity = dict(
127+
controlCharacters=24951, alphanumerics=122647, lowercaseLetters=2063,
128+
punctuationCharacters=770, whitespaces=19, letters=121145,
129+
uppercaseLetters=1733, decimalDigits=590, newlines=7,
130+
capitalizedLetters=31
131+
)
132+
}%
121133
% for Property, Set in Properties.items():
122-
var ${Set}Precomputed: Set<UInt32> = precompute(${Set})
134+
var ${Set}Precomputed: Set<UInt32> =
135+
precompute(${Set}, capacity: ${precomputed_capacity[Set]})
123136
func is${Property}Precomputed(_ c: Character) -> Bool {
124137
return ${Set}Precomputed.contains(c.firstScalar.value)
125138
}
@@ -129,6 +142,7 @@ func setupPrecomputed() {
129142
blackHole(workload)
130143
% for Property, Set in Properties.items():
131144
blackHole(${Set}Precomputed)
145+
%#// print("${Set}: \(${Set}Precomputed.count)")
132146
% end
133147
}
134148

@@ -155,7 +169,7 @@ let workload = """
155169

156170
@inline(never)
157171
public func run_CharacterPropertiesFetch(_ N: Int) {
158-
for _ in 1...N*10 {
172+
for _ in 1...N {
159173
for c in workload {
160174
% for Property, Set in Properties.items():
161175
blackHole(is${Property}(c))
@@ -166,7 +180,7 @@ public func run_CharacterPropertiesFetch(_ N: Int) {
166180

167181
@inline(never)
168182
public func run_CharacterPropertiesStashed(_ N: Int) {
169-
for _ in 1...N*10 {
183+
for _ in 1...N {
170184
for c in workload {
171185
% for Property, Set in Properties.items():
172186
blackHole(is${Property}Stashed(c))
@@ -177,7 +191,7 @@ public func run_CharacterPropertiesStashed(_ N: Int) {
177191

178192
@inline(never)
179193
public func run_CharacterPropertiesStashedMemo(_ N: Int) {
180-
for _ in 1...N*10 {
194+
for _ in 1...N {
181195
for c in workload {
182196
% for Property, Set in Properties.items():
183197
blackHole(is${Property}StashedMemo(c))
@@ -188,7 +202,7 @@ public func run_CharacterPropertiesStashedMemo(_ N: Int) {
188202

189203
@inline(never)
190204
public func run_CharacterPropertiesPrecomputed(_ N: Int) {
191-
for _ in 1...N*10 {
205+
for _ in 1...N {
192206
for c in workload {
193207
% for Property, Set in Properties.items():
194208
blackHole(is${Property}Precomputed(c))

0 commit comments

Comments
 (0)