Skip to content

Commit 87b2473

Browse files
committed
[benchmark] Add string interpolation benchmarks
Add some benchmarks for when the whole interpolated string is small, and when it is very large but every segment is pretty small.
1 parent 0a301aa commit 87b2473

File tree

2 files changed

+63
-2
lines changed

2 files changed

+63
-2
lines changed

benchmark/single-source/StringInterpolation.swift

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ public let StringInterpolation = BenchmarkInfo(
1616
name: "StringInterpolation",
1717
runFunction: run_StringInterpolation,
1818
tags: [.validation, .api, .String])
19+
public let StringInterpolationSmall = BenchmarkInfo(
20+
name: "StringInterpolationSmall",
21+
runFunction: run_StringInterpolationSmall,
22+
tags: [.validation, .api, .String])
23+
public let StringInterpolationManySmallSegments = BenchmarkInfo(
24+
name: "StringInterpolationManySmallSegments",
25+
runFunction: run_StringInterpolationManySmallSegments,
26+
tags: [.validation, .api, .String])
1927

2028
class RefTypePrintable : CustomStringConvertible {
2129
var description: String {
@@ -33,15 +41,66 @@ public func run_StringInterpolation(_ N: Int) {
3341
for _ in 1...100*N {
3442
var result = 0
3543
for _ in 1...reps {
36-
let s = "\(anInt) abcdefdhijklmn \(aRefCountedObject) abcdefdhijklmn \u{01}"
44+
let s: String = getString(
45+
"\(anInt) abcdefdhijklmn \(aRefCountedObject) abcdefdhijklmn \u{01}")
3746
let utf16 = s.utf16
3847

3948
// FIXME: if String is not stored as UTF-16 on this platform, then the
4049
// following operation has a non-trivial cost and needs to be replaced
4150
// with an operation on the native storage type.
42-
result = result &+ Int(utf16[utf16.index(before: utf16.endIndex)])
51+
result = result &+ Int(utf16.last!)
52+
blackHole(s)
53+
}
54+
CheckResults(result == refResult)
55+
}
56+
}
57+
58+
@inline(never)
59+
public func run_StringInterpolationSmall(_ N: Int) {
60+
let reps = 100
61+
let refResult = reps
62+
let anInt: Int64 = 0x42
63+
64+
for _ in 1...100*N {
65+
var result = 0
66+
for _ in 1...reps {
67+
let s: String = getString(
68+
"\(getString("int")): \(anInt) \(getString("abc")) \u{01}")
69+
result = result &+ Int(s.utf8.last!)
70+
blackHole(s)
4371
}
4472
CheckResults(result == refResult)
4573
}
4674
}
4775

76+
@inline(never)
77+
public func run_StringInterpolationManySmallSegments(_ N: Int) {
78+
let numHex = min(UInt64(N), 0x0FFF_FFFF_FFFF_FFFF)
79+
let numOct = min(UInt64(N), 0x0000_03FF_FFFF_FFFF)
80+
let numBin = min(UInt64(N), 0x7FFF)
81+
let segments = [
82+
"abc",
83+
String(numHex, radix: 16),
84+
"0123456789",
85+
String(Double.pi/2),
86+
"*barely* small!",
87+
String(numOct, radix: 8),
88+
"",
89+
String(numBin, radix: 2),
90+
]
91+
assert(segments.count == 8)
92+
93+
func getSegment(_ i: Int) -> String {
94+
return getString(segments[i])
95+
}
96+
97+
let reps = 100
98+
for _ in 1...100*N {
99+
for _ in 1...reps {
100+
blackHole("""
101+
\(getSegment(0)) \(getSegment(1))/\(getSegment(2))_\(getSegment(3))
102+
\(getSegment(4)) \(getSegment(5)), \(getSegment(6))~~\(getSegment(7))
103+
""")
104+
}
105+
}
106+
}

benchmark/utils/main.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@ registerBenchmark(StringComparison)
276276
registerBenchmark(StringEdits)
277277
registerBenchmark(StringEnum)
278278
registerBenchmark(StringInterpolation)
279+
registerBenchmark(StringInterpolationSmall)
280+
registerBenchmark(StringInterpolationManySmallSegments)
279281
registerBenchmark(StringMatch)
280282
registerBenchmark(StringRemoveDupes)
281283
registerBenchmark(StringTests)

0 commit comments

Comments
 (0)