Skip to content

Commit 2fe987c

Browse files
committed
measure more
1 parent a22e5ce commit 2fe987c

2 files changed

Lines changed: 184 additions & 118 deletions

File tree

Tools/scripts/benchmark-baseline.txt

Lines changed: 165 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -3,140 +3,188 @@ pystrhex.c benchmark
33
Timing: best of 7 runs, 50000 iterations each
44

55
bytes.hex() by size:
6-
31.4 ns 0 bytes
7-
46.9 ns 1 byte
8-
47.6 ns 3 bytes
9-
48.1 ns 4 bytes
10-
48.7 ns 7 bytes
11-
50.1 ns 8 bytes
12-
51.1 ns 15 bytes
13-
51.5 ns 16 bytes
14-
55.1 ns 20 bytes
15-
64.8 ns 32 bytes
16-
65.2 ns 33 bytes
17-
90.4 ns 64 bytes
18-
153.4 ns 128 bytes
19-
268.7 ns 256 bytes
20-
514.2 ns 512 bytes
21-
3412.0 ns 4096 bytes
6+
31.2 ns 0 bytes
7+
46.2 ns 1 byte
8+
47.7 ns 3 bytes
9+
47.8 ns 4 bytes
10+
47.7 ns 7 bytes
11+
48.5 ns 8 bytes
12+
50.7 ns 15 bytes
13+
51.2 ns 16 bytes
14+
55.0 ns 20 bytes
15+
64.4 ns 32 bytes
16+
65.4 ns 33 bytes
17+
89.9 ns 64 bytes
18+
152.2 ns 128 bytes
19+
266.7 ns 256 bytes
20+
501.8 ns 512 bytes
21+
3358.7 ns 4096 bytes
2222

2323
bytes.hex(':') with separator (every byte):
24-
80.2 ns 0 bytes
25-
97.7 ns 1 byte
26-
102.4 ns 3 bytes
27-
104.5 ns 4 bytes
28-
110.4 ns 7 bytes
29-
112.0 ns 8 bytes
30-
132.6 ns 15 bytes
31-
135.4 ns 16 bytes
32-
143.2 ns 20 bytes
33-
162.2 ns 32 bytes
34-
160.6 ns 33 bytes
35-
208.0 ns 64 bytes
36-
331.4 ns 128 bytes
37-
563.0 ns 256 bytes
38-
1050.9 ns 512 bytes
39-
7245.8 ns 4096 bytes
24+
76.5 ns 0 bytes
25+
96.3 ns 1 byte
26+
99.8 ns 3 bytes
27+
104.7 ns 4 bytes
28+
111.4 ns 7 bytes
29+
109.3 ns 8 bytes
30+
130.2 ns 15 bytes
31+
133.6 ns 16 bytes
32+
140.4 ns 20 bytes
33+
156.9 ns 32 bytes
34+
156.1 ns 33 bytes
35+
206.9 ns 64 bytes
36+
324.8 ns 128 bytes
37+
553.3 ns 256 bytes
4038

4139
bytes.hex(':', 2) with separator (every 2 bytes):
42-
101.9 ns 3 bytes
43-
104.0 ns 4 bytes
44-
107.2 ns 7 bytes
45-
109.7 ns 8 bytes
46-
121.4 ns 15 bytes
47-
122.0 ns 16 bytes
48-
129.4 ns 20 bytes
49-
144.6 ns 32 bytes
50-
148.8 ns 33 bytes
51-
186.2 ns 64 bytes
52-
284.1 ns 128 bytes
53-
469.9 ns 256 bytes
54-
851.3 ns 512 bytes
55-
4997.0 ns 4096 bytes
40+
105.5 ns 3 bytes
41+
106.7 ns 4 bytes
42+
107.8 ns 7 bytes
43+
109.2 ns 8 bytes
44+
122.4 ns 15 bytes
45+
124.5 ns 16 bytes
46+
128.6 ns 20 bytes
47+
144.5 ns 32 bytes
48+
150.3 ns 33 bytes
49+
180.5 ns 64 bytes
50+
259.9 ns 128 bytes
51+
414.0 ns 256 bytes
52+
53+
bytes.hex('\n', 4) with - (every 4 bytes):
54+
111.5 ns 7 bytes
55+
110.2 ns 8 bytes
56+
120.7 ns 15 bytes
57+
123.5 ns 16 bytes
58+
125.8 ns 20 bytes
59+
143.2 ns 32 bytes
60+
145.8 ns 33 bytes
61+
171.2 ns 64 bytes
62+
242.9 ns 128 bytes
63+
373.5 ns 256 bytes
64+
650.1 ns 512 bytes
65+
4055.4 ns 4096 bytes
66+
67+
bytes.hex('\n', 8) with - (every 8 bytes):
68+
118.9 ns 15 bytes
69+
118.7 ns 16 bytes
70+
121.2 ns 20 bytes
71+
138.0 ns 32 bytes
72+
140.0 ns 33 bytes
73+
164.7 ns 64 bytes
74+
224.7 ns 128 bytes
75+
339.6 ns 256 bytes
76+
586.8 ns 512 bytes
77+
3547.6 ns 4096 bytes
78+
79+
bytes.hex('\n', 16) with - (every 16 bytes):
80+
122.4 ns 20 bytes
81+
129.8 ns 32 bytes
82+
136.4 ns 33 bytes
83+
169.1 ns 64 bytes
84+
221.3 ns 128 bytes
85+
329.9 ns 256 bytes
86+
562.3 ns 512 bytes
87+
3309.3 ns 4096 bytes
88+
89+
bytes.hex('\n', 20) with - (every 20 bytes):
90+
130.8 ns 32 bytes
91+
131.9 ns 33 bytes
92+
161.5 ns 64 bytes
93+
213.1 ns 128 bytes
94+
320.4 ns 256 bytes
95+
550.2 ns 512 bytes
96+
3273.6 ns 4096 bytes
97+
98+
bytes.hex('\n', 32) with newline (every 32 bytes):
99+
128.8 ns 32 bytes
100+
127.5 ns 33 bytes
101+
151.5 ns 64 bytes
102+
202.2 ns 128 bytes
103+
307.7 ns 256 bytes
104+
536.0 ns 512 bytes
105+
3191.3 ns 4096 bytes
56106

57107
bytearray.hex() by size:
58-
33.0 ns 0 bytes
59-
48.5 ns 1 byte
60-
48.1 ns 3 bytes
61-
48.7 ns 4 bytes
62-
50.0 ns 7 bytes
63-
49.7 ns 8 bytes
64-
51.3 ns 15 bytes
65-
51.2 ns 16 bytes
66-
54.5 ns 20 bytes
67-
64.7 ns 32 bytes
68-
64.9 ns 33 bytes
69-
90.0 ns 64 bytes
70-
152.5 ns 128 bytes
71-
265.6 ns 256 bytes
72-
500.9 ns 512 bytes
73-
3383.6 ns 4096 bytes
108+
31.3 ns 0 bytes
109+
48.1 ns 1 byte
110+
47.8 ns 3 bytes
111+
50.6 ns 4 bytes
112+
50.3 ns 7 bytes
113+
50.2 ns 8 bytes
114+
51.9 ns 15 bytes
115+
52.1 ns 16 bytes
116+
55.9 ns 20 bytes
117+
65.3 ns 32 bytes
118+
66.4 ns 33 bytes
119+
93.1 ns 64 bytes
120+
153.5 ns 128 bytes
121+
265.4 ns 256 bytes
122+
506.2 ns 512 bytes
123+
3364.1 ns 4096 bytes
74124

75125
memoryview.hex() by size:
76126
32.5 ns 0 bytes
77-
46.6 ns 1 byte
78-
48.6 ns 3 bytes
79-
48.9 ns 4 bytes
80-
49.6 ns 7 bytes
81-
50.0 ns 8 bytes
82-
53.5 ns 15 bytes
83-
53.1 ns 16 bytes
84-
58.1 ns 20 bytes
85-
66.5 ns 32 bytes
86-
67.5 ns 33 bytes
87-
91.2 ns 64 bytes
88-
153.2 ns 128 bytes
89-
265.9 ns 256 bytes
90-
501.7 ns 512 bytes
91-
3375.4 ns 4096 bytes
127+
47.7 ns 1 byte
128+
48.0 ns 3 bytes
129+
48.3 ns 4 bytes
130+
49.4 ns 7 bytes
131+
49.2 ns 8 bytes
132+
51.8 ns 15 bytes
133+
53.2 ns 16 bytes
134+
56.7 ns 20 bytes
135+
67.6 ns 32 bytes
136+
66.6 ns 33 bytes
137+
91.5 ns 64 bytes
138+
154.3 ns 128 bytes
139+
268.2 ns 256 bytes
140+
508.5 ns 512 bytes
141+
3361.2 ns 4096 bytes
92142

93143
binascii.hexlify() by size:
94-
85.2 ns 0 bytes
95-
102.0 ns 1 byte
96-
99.9 ns 3 bytes
97-
100.2 ns 4 bytes
98-
104.5 ns 7 bytes
99-
102.1 ns 8 bytes
100-
109.3 ns 15 bytes
101-
109.9 ns 16 bytes
102-
114.0 ns 20 bytes
103-
124.8 ns 32 bytes
104-
128.0 ns 33 bytes
105-
152.3 ns 64 bytes
106-
214.4 ns 128 bytes
107-
326.4 ns 256 bytes
108-
568.5 ns 512 bytes
109-
3429.2 ns 4096 bytes
144+
84.0 ns 0 bytes
145+
98.7 ns 1 byte
146+
98.9 ns 3 bytes
147+
101.4 ns 4 bytes
148+
98.9 ns 7 bytes
149+
103.5 ns 8 bytes
150+
109.6 ns 15 bytes
151+
111.8 ns 16 bytes
152+
116.0 ns 20 bytes
153+
129.2 ns 32 bytes
154+
127.7 ns 33 bytes
155+
151.1 ns 64 bytes
156+
212.2 ns 128 bytes
157+
323.5 ns 256 bytes
158+
566.1 ns 512 bytes
159+
3435.1 ns 4096 bytes
110160

111161
binascii.hexlify(sep=':') with separator:
112-
94.4 ns 0 bytes
113-
111.6 ns 1 byte
114-
114.5 ns 3 bytes
115-
116.5 ns 4 bytes
116-
124.2 ns 7 bytes
117-
127.3 ns 8 bytes
118-
136.7 ns 15 bytes
119-
137.5 ns 16 bytes
120-
144.3 ns 20 bytes
121-
164.7 ns 32 bytes
122-
164.3 ns 33 bytes
123-
218.1 ns 64 bytes
124-
334.5 ns 128 bytes
125-
567.5 ns 256 bytes
126-
1061.5 ns 512 bytes
127-
7274.6 ns 4096 bytes
162+
94.7 ns 0 bytes
163+
112.2 ns 1 byte
164+
115.3 ns 3 bytes
165+
114.7 ns 4 bytes
166+
121.8 ns 7 bytes
167+
125.5 ns 8 bytes
168+
138.0 ns 15 bytes
169+
140.3 ns 16 bytes
170+
143.6 ns 20 bytes
171+
161.9 ns 32 bytes
172+
160.8 ns 33 bytes
173+
214.9 ns 64 bytes
174+
333.0 ns 128 bytes
175+
564.2 ns 256 bytes
128176

129177
hashlib hexdigest (hash + hex conversion):
130-
562.6 ns md5 (16 byte digest)
131-
527.4 ns sha1 (20 byte digest)
132-
537.2 ns sha256 (32 byte digest)
133-
746.1 ns sha512 (64 byte digest)
178+
557.2 ns md5 (16 byte digest)
179+
522.8 ns sha1 (20 byte digest)
180+
532.5 ns sha256 (32 byte digest)
181+
726.3 ns sha512 (64 byte digest)
134182

135183
hashlib hexdigest only (hex conversion, pre-computed hash):
136-
318.8 ns md5 (16 byte digest)
137-
283.2 ns sha1 (20 byte digest)
138-
298.2 ns sha256 (32 byte digest)
139-
504.5 ns sha512 (64 byte digest)
184+
324.7 ns md5 (16 byte digest)
185+
282.0 ns sha1 (20 byte digest)
186+
294.9 ns sha256 (32 byte digest)
187+
500.5 ns sha512 (64 byte digest)
140188

141189
==================================================
142190
Done.

Tools/scripts/pystrhex_benchmark.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ def bench_bytes_hex_sep():
6262
"""Benchmark bytes.hex() with separator."""
6363
print("\nbytes.hex(':') with separator (every byte):")
6464
for size in SIZES:
65+
if size > 256:
66+
continue
6567
data = DATA[size]
6668
ns = run_benchmark(lambda d=data: d.hex(':'))
6769
print(f" {ns:7.1f} ns {format_size(size)}")
@@ -72,13 +74,26 @@ def bench_bytes_hex_sep_group():
7274
print("\nbytes.hex(':', 2) with separator (every 2 bytes):")
7375
# Skip 0 and 1 byte sizes since grouping doesn't apply well
7476
for size in SIZES:
75-
if size < 2:
77+
if size < 2 or size > 256:
7678
continue
7779
data = DATA[size]
7880
ns = run_benchmark(lambda d=data: d.hex(':', 2))
7981
print(f" {ns:7.1f} ns {format_size(size)}")
8082

8183

84+
def bench_bytes_hex_sep_4_thru_20():
85+
"""Benchmark bytes.hex() with separators in the 4-20 bytes range."""
86+
for sep_width in (4, 8, 16, 20):
87+
print(f"\nbytes.hex('\\n', {sep_width}) with - (every {sep_width} bytes):")
88+
# Only test sizes > width where this grouping is meaningful
89+
for size in SIZES:
90+
if size <= sep_width:
91+
continue
92+
data = DATA[size]
93+
ns = run_benchmark(lambda d=data: d.hex('-', sep_width))
94+
print(f" {ns:7.1f} ns {format_size(size)}")
95+
96+
8297
def bench_bytes_hex_newline_32():
8398
"""Benchmark bytes.hex() with newline separator every 32 bytes.
8499
@@ -125,6 +140,8 @@ def bench_binascii_hexlify_sep():
125140
"""Benchmark binascii.hexlify() with separator."""
126141
print("\nbinascii.hexlify(sep=':') with separator:")
127142
for size in SIZES:
143+
if size > 256:
144+
continue
128145
data = DATA[size]
129146
ns = run_benchmark(lambda d=data: binascii.hexlify(d, ':'))
130147
print(f" {ns:7.1f} ns {format_size(size)}")
@@ -194,6 +211,7 @@ def bench_hash_hexdigest_only():
194211
bench_bytes_hex()
195212
bench_bytes_hex_sep()
196213
bench_bytes_hex_sep_group()
214+
bench_bytes_hex_sep_4_thru_20()
197215
bench_bytes_hex_newline_32()
198216
bench_bytearray_hex()
199217
bench_memoryview_hex()

0 commit comments

Comments
 (0)