Skip to content

Commit e783bef

Browse files
authored
Merge pull request #13739 from milseman/char_prop_bench
[benchmark] Add a CharacterProperties benchmark
2 parents e64977e + 1c2954b commit e783bef

File tree

4 files changed

+282
-0
lines changed

4 files changed

+282
-0
lines changed

benchmark/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ set(SWIFT_BENCH_MODULES
4747
single-source/CaptureProp
4848
single-source/CharacterLiteralsLarge
4949
single-source/CharacterLiteralsSmall
50+
single-source/CharacterProperties
5051
single-source/Chars
5152
single-source/ClassArrayGetter
5253
single-source/DeadArray
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
//===--- CharacterProperties.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+
////////////////////////////////////////////////////////////////////////////////
14+
// WARNING: This file is manually generated from .gyb template and should not
15+
// be directly modified. Instead, make changes to CharacterProperties.swift.gyb
16+
// and run scripts/generate_harness/generate_harness.py to regenerate this file.
17+
////////////////////////////////////////////////////////////////////////////////
18+
19+
import TestsUtils
20+
import Foundation
21+
22+
public let CharacterPropertiesFetch = BenchmarkInfo(
23+
name: "CharacterPropertiesFetch",
24+
runFunction: run_CharacterPropertiesFetch,
25+
tags: [.validation, .api, .String])
26+
27+
public let CharacterPropertiesStashed = BenchmarkInfo(
28+
name: "CharacterPropertiesStashed",
29+
runFunction: run_CharacterPropertiesStashed,
30+
tags: [.validation, .api, .String])
31+
32+
33+
extension Character {
34+
var firstScalar: UnicodeScalar { return unicodeScalars.first! }
35+
}
36+
37+
38+
// Fetch the CharacterSet for every call
39+
func isControl(_ c: Character) -> Bool {
40+
return CharacterSet.controlCharacters.contains(c.firstScalar)
41+
}
42+
func isAlphanumeric(_ c: Character) -> Bool {
43+
return CharacterSet.alphanumerics.contains(c.firstScalar)
44+
}
45+
func isLowercase(_ c: Character) -> Bool {
46+
return CharacterSet.lowercaseLetters.contains(c.firstScalar)
47+
}
48+
func isPunctuation(_ c: Character) -> Bool {
49+
return CharacterSet.punctuationCharacters.contains(c.firstScalar)
50+
}
51+
func isWhitespace(_ c: Character) -> Bool {
52+
return CharacterSet.whitespaces.contains(c.firstScalar)
53+
}
54+
func isLetter(_ c: Character) -> Bool {
55+
return CharacterSet.letters.contains(c.firstScalar)
56+
}
57+
func isUppercase(_ c: Character) -> Bool {
58+
return CharacterSet.uppercaseLetters.contains(c.firstScalar)
59+
}
60+
func isDecimal(_ c: Character) -> Bool {
61+
return CharacterSet.decimalDigits.contains(c.firstScalar)
62+
}
63+
func isNewline(_ c: Character) -> Bool {
64+
return CharacterSet.newlines.contains(c.firstScalar)
65+
}
66+
func isCapitalized(_ c: Character) -> Bool {
67+
return CharacterSet.capitalizedLetters.contains(c.firstScalar)
68+
}
69+
70+
// Stash the set
71+
let controlCharacters = CharacterSet.controlCharacters
72+
func isControlStashed(_ c: Character) -> Bool {
73+
return controlCharacters.contains(c.firstScalar)
74+
}
75+
let alphanumerics = CharacterSet.alphanumerics
76+
func isAlphanumericStashed(_ c: Character) -> Bool {
77+
return alphanumerics.contains(c.firstScalar)
78+
}
79+
let lowercaseLetters = CharacterSet.lowercaseLetters
80+
func isLowercaseStashed(_ c: Character) -> Bool {
81+
return lowercaseLetters.contains(c.firstScalar)
82+
}
83+
let punctuationCharacters = CharacterSet.punctuationCharacters
84+
func isPunctuationStashed(_ c: Character) -> Bool {
85+
return punctuationCharacters.contains(c.firstScalar)
86+
}
87+
let whitespaces = CharacterSet.whitespaces
88+
func isWhitespaceStashed(_ c: Character) -> Bool {
89+
return whitespaces.contains(c.firstScalar)
90+
}
91+
let letters = CharacterSet.letters
92+
func isLetterStashed(_ c: Character) -> Bool {
93+
return letters.contains(c.firstScalar)
94+
}
95+
let uppercaseLetters = CharacterSet.uppercaseLetters
96+
func isUppercaseStashed(_ c: Character) -> Bool {
97+
return uppercaseLetters.contains(c.firstScalar)
98+
}
99+
let decimalDigits = CharacterSet.decimalDigits
100+
func isDecimalStashed(_ c: Character) -> Bool {
101+
return decimalDigits.contains(c.firstScalar)
102+
}
103+
let newlines = CharacterSet.newlines
104+
func isNewlineStashed(_ c: Character) -> Bool {
105+
return newlines.contains(c.firstScalar)
106+
}
107+
let capitalizedLetters = CharacterSet.capitalizedLetters
108+
func isCapitalizedStashed(_ c: Character) -> Bool {
109+
return capitalizedLetters.contains(c.firstScalar)
110+
}
111+
112+
// Compute on the fly
113+
//
114+
// TODO: If UnicodeScalars ever exposes category, etc., implement the others!
115+
func isNewlineComputed(_ c: Character) -> Bool {
116+
switch c.firstScalar.value {
117+
case 0x000A...0x000D: return true
118+
case 0x0085: return true
119+
case 0x2028...0x2029: return true
120+
default: return false
121+
}
122+
}
123+
124+
let workload = """
125+
the quick brown 🦊 jumped over the lazy 🐶.
126+
в чащах юга жил-был цитрус? да, но фальшивый экземпляр
127+
𓀀𓀤𓁓𓁲𓃔𓃗𓃀𓃁𓃂𓃃𓆌𓆍𓆎𓆏𓆐𓆑𓆒𓆲𓁿
128+
🝁ꃕ躍‾∾📦⺨
129+
👍👩‍👩‍👧‍👧👨‍👨‍👦‍👦🇺🇸🇨🇦🇲🇽👍🏻👍🏼👍🏽👍🏾👍🏿
130+
Lorem ipsum something something something...
131+
"""
132+
133+
@inline(never)
134+
public func run_CharacterPropertiesFetch(_ N: Int) {
135+
for _ in 1...N {
136+
for c in workload {
137+
blackHole(isControl(c))
138+
blackHole(isAlphanumeric(c))
139+
blackHole(isLowercase(c))
140+
blackHole(isPunctuation(c))
141+
blackHole(isWhitespace(c))
142+
blackHole(isLetter(c))
143+
blackHole(isUppercase(c))
144+
blackHole(isDecimal(c))
145+
blackHole(isNewline(c))
146+
blackHole(isCapitalized(c))
147+
}
148+
}
149+
}
150+
151+
@inline(never)
152+
public func run_CharacterPropertiesStashed(_ N: Int) {
153+
for _ in 1...N {
154+
for c in workload {
155+
blackHole(isControlStashed(c))
156+
blackHole(isAlphanumericStashed(c))
157+
blackHole(isLowercaseStashed(c))
158+
blackHole(isPunctuationStashed(c))
159+
blackHole(isWhitespaceStashed(c))
160+
blackHole(isLetterStashed(c))
161+
blackHole(isUppercaseStashed(c))
162+
blackHole(isDecimalStashed(c))
163+
blackHole(isNewlineStashed(c))
164+
blackHole(isCapitalizedStashed(c))
165+
}
166+
}
167+
}
168+
169+
// TODO: run_CharacterPropertiesComputed
170+
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
//===--- CharacterProperties.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, make changes to CharacterProperties.swift.gyb
17+
// and run scripts/generate_harness/generate_harness.py to regenerate this file.
18+
////////////////////////////////////////////////////////////////////////////////
19+
20+
import TestsUtils
21+
import Foundation
22+
23+
public let CharacterPropertiesFetch = BenchmarkInfo(
24+
name: "CharacterPropertiesFetch",
25+
runFunction: run_CharacterPropertiesFetch,
26+
tags: [.validation, .api, .String])
27+
28+
public let CharacterPropertiesStashed = BenchmarkInfo(
29+
name: "CharacterPropertiesStashed",
30+
runFunction: run_CharacterPropertiesStashed,
31+
tags: [.validation, .api, .String])
32+
33+
34+
extension Character {
35+
var firstScalar: UnicodeScalar { return unicodeScalars.first! }
36+
}
37+
38+
% Properties = { "Alphanumeric": "alphanumerics", "Capitalized": "capitalizedLetters", \
39+
% "Control": "controlCharacters", \
40+
% "Decimal": "decimalDigits", \
41+
% "Letter": "letters", \
42+
% "Lowercase": "lowercaseLetters", \
43+
% "Uppercase": "uppercaseLetters", \
44+
% "Newline": "newlines", \
45+
% "Whitespace": "whitespaces", \
46+
% "Punctuation": "punctuationCharacters" \
47+
% }
48+
49+
// Fetch the CharacterSet for every call
50+
% for Property, Set in Properties.items():
51+
func is${Property}(_ c: Character) -> Bool {
52+
return CharacterSet.${Set}.contains(c.firstScalar)
53+
}
54+
% end
55+
56+
// Stash the set
57+
% for Property, Set in Properties.items():
58+
let ${Set} = CharacterSet.${Set}
59+
func is${Property}Stashed(_ c: Character) -> Bool {
60+
return ${Set}.contains(c.firstScalar)
61+
}
62+
% end
63+
64+
// Compute on the fly
65+
//
66+
// TODO: If UnicodeScalars ever exposes category, etc., implement the others!
67+
func isNewlineComputed(_ c: Character) -> Bool {
68+
switch c.firstScalar.value {
69+
case 0x000A...0x000D: return true
70+
case 0x0085: return true
71+
case 0x2028...0x2029: return true
72+
default: return false
73+
}
74+
}
75+
76+
let workload = """
77+
the quick brown 🦊 jumped over the lazy 🐶.
78+
в чащах юга жил-был цитрус? да, но фальшивый экземпляр
79+
𓀀𓀤𓁓𓁲𓃔𓃗𓃀𓃁𓃂𓃃𓆌𓆍𓆎𓆏𓆐𓆑𓆒𓆲𓁿
80+
🝁ꃕ躍‾∾📦⺨
81+
👍👩‍👩‍👧‍👧👨‍👨‍👦‍👦🇺🇸🇨🇦🇲🇽👍🏻👍🏼👍🏽👍🏾👍🏿
82+
Lorem ipsum something something something...
83+
"""
84+
85+
@inline(never)
86+
public func run_CharacterPropertiesFetch(_ N: Int) {
87+
for _ in 1...N {
88+
for c in workload {
89+
% for Property, Set in Properties.items():
90+
blackHole(is${Property}(c))
91+
% end
92+
}
93+
}
94+
}
95+
96+
@inline(never)
97+
public func run_CharacterPropertiesStashed(_ N: Int) {
98+
for _ in 1...N {
99+
for c in workload {
100+
% for Property, Set in Properties.items():
101+
blackHole(is${Property}Stashed(c))
102+
% end
103+
}
104+
}
105+
}
106+
107+
// TODO: run_CharacterPropertiesComputed
108+

benchmark/utils/main.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import ByteSwap
3232
import CString
3333
import Calculator
3434
import CaptureProp
35+
import CharacterProperties
3536
import CharacterLiteralsLarge
3637
import CharacterLiteralsSmall
3738
import Chars
@@ -153,6 +154,8 @@ registerBenchmark(ByteSwap)
153154
registerBenchmark(CString)
154155
registerBenchmark(Calculator)
155156
registerBenchmark(CaptureProp)
157+
registerBenchmark(CharacterPropertiesFetch)
158+
registerBenchmark(CharacterPropertiesStashed)
156159
registerBenchmark(CharacterLiteralsLarge)
157160
registerBenchmark(CharacterLiteralsSmall)
158161
registerBenchmark(Chars)

0 commit comments

Comments
 (0)