Skip to content

Commit bdad47a

Browse files
authored
Create benchmarks for base64 (#950)
1 parent b2d323e commit bdad47a

File tree

3 files changed

+209
-26
lines changed

3 files changed

+209
-26
lines changed
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2024 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+
import Benchmark
14+
import func Benchmark.blackHole
15+
16+
#if os(macOS) && USE_PACKAGE
17+
import FoundationEssentials
18+
#else
19+
import Foundation
20+
#endif
21+
22+
#if !FOUNDATION_FRAMEWORK
23+
private func autoreleasepool<T>(_ block: () -> T) -> T { block() }
24+
#endif
25+
26+
#if canImport(Glibc)
27+
import Glibc
28+
#endif
29+
#if canImport(Darwin)
30+
import Darwin
31+
#endif
32+
33+
let benchmarks = {
34+
Benchmark(
35+
"base64-encode-jwtHeader-toString-noOptions",
36+
configuration: Benchmark.Configuration(
37+
metrics: [.cpuTotal, .mallocCountTotal, .throughput],
38+
scalingFactor: .kilo,
39+
maxDuration: .seconds(3)
40+
)
41+
) { benchmark in
42+
for _ in benchmark.scaledIterations {
43+
autoreleasepool {
44+
blackHole(jwtHeaderTestData.base64EncodedString())
45+
}
46+
}
47+
}
48+
49+
Benchmark(
50+
"base64-encode-1MB-toString-noOptions",
51+
configuration: Benchmark.Configuration(
52+
metrics: [.cpuTotal, .mallocCountTotal, .throughput],
53+
scalingFactor: .one,
54+
maxDuration: .seconds(3)
55+
)
56+
) { benchmark in
57+
for _ in benchmark.scaledIterations {
58+
autoreleasepool {
59+
blackHole(oneMBTestData.base64EncodedString())
60+
}
61+
}
62+
}
63+
64+
Benchmark(
65+
"base64-encode-1MB-toData-noOptions",
66+
configuration: Benchmark.Configuration(
67+
metrics: [.cpuTotal, .mallocCountTotal, .throughput],
68+
scalingFactor: .one,
69+
maxDuration: .seconds(3)
70+
)
71+
) { benchmark in
72+
for _ in benchmark.scaledIterations {
73+
autoreleasepool {
74+
blackHole(oneMBTestData.base64EncodedData())
75+
}
76+
}
77+
}
78+
79+
Benchmark(
80+
"base64-encode-1MB-toString-lineLength64",
81+
configuration: Benchmark.Configuration(
82+
metrics: [.cpuTotal, .mallocCountTotal, .throughput],
83+
scalingFactor: .one,
84+
maxDuration: .seconds(3)
85+
)
86+
) { benchmark in
87+
for _ in benchmark.scaledIterations {
88+
autoreleasepool {
89+
blackHole(oneMBTestData.base64EncodedString(options: .lineLength64Characters))
90+
}
91+
}
92+
}
93+
94+
Benchmark(
95+
"base64-decode-jwtHeader-fromString-noOptions",
96+
configuration: Benchmark.Configuration(
97+
metrics: [.cpuTotal, .mallocCountTotal, .throughput],
98+
scalingFactor: .kilo,
99+
maxDuration: .seconds(3)
100+
)
101+
) { benchmark in
102+
let base64DataString = jwtHeaderTestData.base64EncodedString()
103+
104+
benchmark.startMeasurement()
105+
106+
for _ in benchmark.scaledIterations {
107+
autoreleasepool {
108+
blackHole(Data(base64Encoded: base64DataString))
109+
}
110+
}
111+
}
112+
113+
Benchmark(
114+
"base64-decode-1MB-fromString-noOptions",
115+
configuration: Benchmark.Configuration(
116+
metrics: [.cpuTotal, .mallocCountTotal, .throughput],
117+
scalingFactor: .one,
118+
maxDuration: .seconds(3)
119+
)
120+
) { benchmark in
121+
let base64DataString = oneMBTestData.base64EncodedString()
122+
123+
benchmark.startMeasurement()
124+
125+
for _ in benchmark.scaledIterations {
126+
autoreleasepool {
127+
blackHole(Data(base64Encoded: base64DataString))
128+
}
129+
}
130+
}
131+
132+
Benchmark(
133+
"base64-decode-1MB-fromData-noOptions",
134+
configuration: Benchmark.Configuration(
135+
metrics: [.cpuTotal, .mallocCountTotal, .throughput],
136+
scalingFactor: .one,
137+
maxDuration: .seconds(3)
138+
)
139+
) { benchmark in
140+
let base64Data = oneMBTestData.base64EncodedData()
141+
142+
benchmark.startMeasurement()
143+
144+
for _ in benchmark.scaledIterations {
145+
autoreleasepool {
146+
blackHole(Data(base64Encoded: base64Data))
147+
}
148+
}
149+
}
150+
151+
Benchmark(
152+
"base64-decode-1MB-fromData-noOptions-invalidAfter257bytes",
153+
configuration: Benchmark.Configuration(
154+
metrics: [.cpuTotal, .mallocCountTotal, .throughput],
155+
scalingFactor: .kilo,
156+
maxDuration: .seconds(3)
157+
)
158+
) { benchmark in
159+
var base64Data = oneMBTestData.base64EncodedData()
160+
base64Data[257] = 0
161+
162+
benchmark.startMeasurement()
163+
164+
for _ in benchmark.scaledIterations {
165+
autoreleasepool {
166+
blackHole(Data(base64Encoded: base64Data))
167+
}
168+
}
169+
}
170+
171+
Benchmark(
172+
"base64-decode-1MB-fromString-lineLength64",
173+
configuration: Benchmark.Configuration(
174+
metrics: [.cpuTotal, .mallocCountTotal, .throughput],
175+
scalingFactor: .one,
176+
maxDuration: .seconds(3)
177+
)
178+
) { benchmark in
179+
let base64DataString = oneMBTestData.base64EncodedString(options: .lineLength64Characters)
180+
181+
benchmark.startMeasurement()
182+
183+
for _ in benchmark.scaledIterations {
184+
autoreleasepool {
185+
blackHole(Data(base64Encoded: base64DataString, options: .ignoreUnknownCharacters))
186+
}
187+
}
188+
}
189+
190+
}
191+
192+
let jwtHeaderTestData = Data(#"{"alg":"ES256","typ":"JWT"}"#.utf8)
193+
let oneMBTestData = createTestData(count: 1000 * 1024)
194+
func createTestData(count: Int) -> Data {
195+
var data = Data(count: count)
196+
for index in data.indices {
197+
data[index] = UInt8(index % Int(UInt8.max))
198+
}
199+
return data
200+
}

Benchmarks/Benchmarks/DataIO/BenchmarkDataIO.swift

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -151,30 +151,4 @@ let benchmarks = {
151151
) { benchmark in
152152
blackHole(try Data(contentsOf: testPath))
153153
}
154-
155-
// MARK: base64
156-
157-
Benchmark("base64-encode", configuration: .init(
158-
metrics: [.cpuTotal, .mallocCountTotal, .peakMemoryResident, .throughput],
159-
scalingFactor: .kilo)
160-
) { benchmark in
161-
for _ in benchmark.scaledIterations {
162-
autoreleasepool {
163-
blackHole(base64Data.base64EncodedString())
164-
}
165-
}
166-
}
167-
168-
169-
Benchmark("base64-decode", configuration: .init(
170-
metrics: [.cpuTotal, .mallocCountTotal, .peakMemoryResident, .throughput],
171-
scalingFactor: .kilo)
172-
) { benchmark in
173-
for _ in benchmark.scaledIterations {
174-
autoreleasepool {
175-
blackHole(Data(base64Encoded: base64DataString))
176-
}
177-
}
178-
}
179-
180154
}

Benchmarks/Package.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,15 @@ let package = Package(
164164
.plugin(name: "BenchmarkPlugin", package: "package-benchmark")
165165
]
166166
),
167+
.executableTarget(
168+
name: "Base64Benchmarks",
169+
dependencies: targetDependency,
170+
path: "Benchmarks/Base64",
171+
swiftSettings: swiftSettings,
172+
plugins: [
173+
.plugin(name: "BenchmarkPlugin", package: "package-benchmark")
174+
]
175+
),
167176
]
168177
)
169178

0 commit comments

Comments
 (0)