Skip to content

Commit d0aa8d0

Browse files
committed
Add bm_base64 covering common base64 module APIs
1 parent bb8495c commit d0aa8d0

File tree

2 files changed

+235
-0
lines changed

2 files changed

+235
-0
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[project]
2+
name = "pyperformance_bm_base64"
3+
requires-python = ">=3.8"
4+
dependencies = ["pyperf"]
5+
urls = {repository = "https://github.com/python/pyperformance"}
6+
dynamic = ["version"]
7+
8+
[tool.pyperformance]
9+
name = "base64"
10+
tags = "serialize"
Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
"""Benchmark for the base64 module's primary public APIs.
2+
3+
Tests encoding and decoding performance across various variants
4+
and data sizes.
5+
"""
6+
7+
import base64
8+
import random
9+
import pyperf
10+
11+
12+
# Generate test data with fixed seed for reproducibility
13+
random.seed(12345)
14+
DATA_TINY = bytes(random.randrange(256) for _ in range(20))
15+
DATA_SMALL = bytes(random.randrange(256) for _ in range(127)) # odd on purpose
16+
DATA_MEDIUM = bytes(random.randrange(256) for _ in range(3072))
17+
DATA_LARGE = bytes(random.randrange(256) for _ in range(102400))
18+
19+
# Pre-encoded data for decode benchmarks
20+
B64_TINY = base64.b64encode(DATA_TINY)
21+
B64_SMALL = base64.b64encode(DATA_SMALL)
22+
B64_MEDIUM = base64.b64encode(DATA_MEDIUM)
23+
B64_LARGE = base64.b64encode(DATA_LARGE)
24+
25+
B64_URLSAFE_TINY = base64.urlsafe_b64encode(DATA_TINY)
26+
B64_URLSAFE_SMALL = base64.urlsafe_b64encode(DATA_SMALL)
27+
B64_URLSAFE_MEDIUM = base64.urlsafe_b64encode(DATA_MEDIUM)
28+
# large intentionally excluded... c'mon people, they're URLs!
29+
30+
B32_TINY = base64.b32encode(DATA_TINY)
31+
B32_SMALL = base64.b32encode(DATA_SMALL)
32+
B32_MEDIUM = base64.b32encode(DATA_MEDIUM)
33+
B32_LARGE = base64.b32encode(DATA_LARGE)
34+
35+
B16_TINY = base64.b16encode(DATA_TINY)
36+
B16_SMALL = base64.b16encode(DATA_SMALL)
37+
B16_MEDIUM = base64.b16encode(DATA_MEDIUM)
38+
B16_LARGE = base64.b16encode(DATA_LARGE)
39+
40+
A85_TINY = base64.a85encode(DATA_TINY)
41+
A85_SMALL = base64.a85encode(DATA_SMALL)
42+
A85_MEDIUM = base64.a85encode(DATA_MEDIUM)
43+
A85_LARGE = base64.a85encode(DATA_LARGE)
44+
45+
A85_WRAP_TINY = base64.a85encode(DATA_TINY, wrapcol=76)
46+
A85_WRAP_SMALL = base64.a85encode(DATA_SMALL, wrapcol=76)
47+
A85_WRAP_MEDIUM = base64.a85encode(DATA_MEDIUM, wrapcol=76)
48+
A85_WRAP_LARGE = base64.a85encode(DATA_LARGE, wrapcol=76)
49+
50+
B85_TINY = base64.b85encode(DATA_TINY)
51+
B85_SMALL = base64.b85encode(DATA_SMALL)
52+
B85_MEDIUM = base64.b85encode(DATA_MEDIUM)
53+
B85_LARGE = base64.b85encode(DATA_LARGE)
54+
55+
56+
def bench_b64encode(loops):
57+
range_it = range(loops)
58+
t0 = pyperf.perf_counter()
59+
for _ in range_it:
60+
base64.b64encode(DATA_TINY)
61+
base64.b64encode(DATA_SMALL)
62+
base64.b64encode(DATA_MEDIUM)
63+
base64.b64encode(DATA_LARGE)
64+
return pyperf.perf_counter() - t0
65+
66+
67+
def bench_b64decode(loops):
68+
range_it = range(loops)
69+
t0 = pyperf.perf_counter()
70+
for _ in range_it:
71+
base64.b64decode(B64_TINY)
72+
base64.b64decode(B64_SMALL)
73+
base64.b64decode(B64_MEDIUM)
74+
base64.b64decode(B64_LARGE)
75+
return pyperf.perf_counter() - t0
76+
77+
78+
def bench_urlsafe_b64encode(loops):
79+
range_it = range(loops)
80+
t0 = pyperf.perf_counter()
81+
for _ in range_it:
82+
base64.urlsafe_b64encode(DATA_TINY)
83+
base64.urlsafe_b64encode(DATA_SMALL)
84+
base64.urlsafe_b64encode(DATA_MEDIUM)
85+
return pyperf.perf_counter() - t0
86+
87+
88+
def bench_urlsafe_b64decode(loops):
89+
range_it = range(loops)
90+
t0 = pyperf.perf_counter()
91+
for _ in range_it:
92+
base64.urlsafe_b64decode(B64_URLSAFE_TINY)
93+
base64.urlsafe_b64decode(B64_URLSAFE_SMALL)
94+
base64.urlsafe_b64decode(B64_URLSAFE_MEDIUM)
95+
return pyperf.perf_counter() - t0
96+
97+
98+
def bench_b32encode(loops):
99+
range_it = range(loops)
100+
t0 = pyperf.perf_counter()
101+
for _ in range_it:
102+
base64.b32encode(DATA_TINY)
103+
base64.b32encode(DATA_SMALL)
104+
base64.b32encode(DATA_MEDIUM)
105+
base64.b32encode(DATA_LARGE)
106+
return pyperf.perf_counter() - t0
107+
108+
109+
def bench_b32decode(loops):
110+
range_it = range(loops)
111+
t0 = pyperf.perf_counter()
112+
for _ in range_it:
113+
base64.b32decode(B32_TINY)
114+
base64.b32decode(B32_SMALL)
115+
base64.b32decode(B32_MEDIUM)
116+
base64.b32decode(B32_LARGE)
117+
return pyperf.perf_counter() - t0
118+
119+
120+
def bench_b16encode(loops):
121+
range_it = range(loops)
122+
t0 = pyperf.perf_counter()
123+
for _ in range_it:
124+
base64.b16encode(DATA_TINY)
125+
base64.b16encode(DATA_SMALL)
126+
base64.b16encode(DATA_MEDIUM)
127+
base64.b16encode(DATA_LARGE)
128+
return pyperf.perf_counter() - t0
129+
130+
131+
def bench_b16decode(loops):
132+
range_it = range(loops)
133+
t0 = pyperf.perf_counter()
134+
for _ in range_it:
135+
base64.b16decode(B16_TINY)
136+
base64.b16decode(B16_SMALL)
137+
base64.b16decode(B16_MEDIUM)
138+
base64.b16decode(B16_LARGE)
139+
return pyperf.perf_counter() - t0
140+
141+
142+
def bench_a85encode(loops):
143+
range_it = range(loops)
144+
t0 = pyperf.perf_counter()
145+
for _ in range_it:
146+
base64.a85encode(DATA_TINY)
147+
base64.a85encode(DATA_SMALL)
148+
base64.a85encode(DATA_MEDIUM)
149+
base64.a85encode(DATA_LARGE)
150+
return pyperf.perf_counter() - t0
151+
152+
153+
def bench_a85decode(loops):
154+
range_it = range(loops)
155+
t0 = pyperf.perf_counter()
156+
for _ in range_it:
157+
base64.a85decode(A85_TINY)
158+
base64.a85decode(A85_SMALL)
159+
base64.a85decode(A85_MEDIUM)
160+
base64.a85decode(A85_LARGE)
161+
return pyperf.perf_counter() - t0
162+
163+
164+
def bench_b85encode(loops):
165+
range_it = range(loops)
166+
t0 = pyperf.perf_counter()
167+
for _ in range_it:
168+
base64.b85encode(DATA_TINY)
169+
base64.b85encode(DATA_SMALL)
170+
base64.b85encode(DATA_MEDIUM)
171+
base64.b85encode(DATA_LARGE)
172+
return pyperf.perf_counter() - t0
173+
174+
175+
def bench_b85decode(loops):
176+
range_it = range(loops)
177+
t0 = pyperf.perf_counter()
178+
for _ in range_it:
179+
base64.b85decode(B85_TINY)
180+
base64.b85decode(B85_SMALL)
181+
base64.b85decode(B85_MEDIUM)
182+
base64.b85decode(B85_LARGE)
183+
return pyperf.perf_counter() - t0
184+
185+
186+
def bench_a85encode_wrapcol(loops):
187+
range_it = range(loops)
188+
t0 = pyperf.perf_counter()
189+
for _ in range_it:
190+
base64.a85encode(DATA_TINY, wrapcol=76)
191+
base64.a85encode(DATA_SMALL, wrapcol=76)
192+
base64.a85encode(DATA_MEDIUM, wrapcol=76)
193+
base64.a85encode(DATA_LARGE, wrapcol=76)
194+
return pyperf.perf_counter() - t0
195+
196+
197+
def bench_b64decode_validate(loops):
198+
range_it = range(loops)
199+
t0 = pyperf.perf_counter()
200+
for _ in range_it:
201+
base64.b64decode(B64_TINY, validate=True)
202+
base64.b64decode(B64_SMALL, validate=True)
203+
base64.b64decode(B64_MEDIUM, validate=True)
204+
base64.b64decode(B64_LARGE, validate=True)
205+
return pyperf.perf_counter() - t0
206+
207+
208+
if __name__ == "__main__":
209+
runner = pyperf.Runner()
210+
runner.metadata['description'] = "Benchmark base64 module encoding/decoding"
211+
212+
runner.bench_time_func('base64_encode', bench_b64encode)
213+
runner.bench_time_func('base64_decode', bench_b64decode)
214+
runner.bench_time_func('base64_decode_validate', bench_b64decode_validate)
215+
runner.bench_time_func('urlsafe_base64_encode', bench_urlsafe_b64encode)
216+
runner.bench_time_func('urlsafe_base64_decode', bench_urlsafe_b64decode)
217+
runner.bench_time_func('base32_encode', bench_b32encode)
218+
runner.bench_time_func('base32_decode', bench_b32decode)
219+
runner.bench_time_func('base16_encode', bench_b16encode)
220+
runner.bench_time_func('base16_decode', bench_b16decode)
221+
runner.bench_time_func('ascii85_encode', bench_a85encode)
222+
runner.bench_time_func('ascii85_decode', bench_a85decode)
223+
runner.bench_time_func('ascii85_encode_wrapcol', bench_a85encode_wrapcol)
224+
runner.bench_time_func('base85_encode', bench_b85encode)
225+
runner.bench_time_func('base85_decode', bench_b85decode)

0 commit comments

Comments
 (0)