Repository navigation
Commit 7c2bb06
gh-160931: Speed up bytes construction from exact bytes and int
Since 3.11 added `bytes.__bytes__`, bytes(b) for an exact bytes binds
and calls that method only to get b back. Return an exact bytes
argument directly, like PyObject_Bytes() and PyBytes_FromObject() do,
and skip the lookup, which always misses, for an exact int.
How bytes(x) resolves is unchanged: both types are immutable, so the
skipped lookup and call could only ever produce the same result, and
subclasses, including bool, still look up `__bytes__` first. These
cases just get there faster.
pyperf, PGO+LTO, interleaved A/B on 19270d3 (A/A spread <= 1.05x):
| Benchmark | main | patch |
|-------------------|:-------:|:---------------------:|
| bytes(b) | 28.5 ns | 12.8 ns: 2.22x faster |
| Sub(b) | 51.7 ns | 36.0 ns: 1.44x faster |
| bytes(16) | 23.5 ns | 21.0 ns: 1.12x faster |
| bytes(hb) | 38.7 ns | 38.0 ns: 1.02x faster |
| bytes(s, 'ascii') | 26.5 ns | 27.1 ns: 1.02x slower |
| bytes() | 10.7 ns | 11.1 ns: 1.03x slower |
Not significant: bytes(ba), bytes(l), bytes(mv). The small slowdowns
(1.02-1.03x) are within the noise on my machine.
import pyperf
runner = pyperf.Runner()
for stmt in ["bytes(b)", "bytes(16)", "bytes(ba)", "bytes(mv)", "bytes(l)",
"bytes(s, 'ascii')", "bytes(hb)", "Sub(b)", "bytes()"]:
runner.timeit(stmt, stmt,
"b = b'abcdefghijklmnop'; ba = bytearray(b); mv = memoryview(b); "
"l = list(range(16)); s = 'abcdefghijklmnop'\n"
"class Sub(bytes): pass\n"
"class HB:\n def __bytes__(self): return b\n"
"hb = HB()")
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>1 parent ef1fce0 commit 7c2bb06
2 files changed
Lines changed: 10 additions & 2 deletions
File tree
- Misc/NEWS.d/next/Core_and_Builtins
- Objects
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2970 | 2970 | | |
2971 | 2971 | | |
2972 | 2972 | | |
| 2973 | + | |
| 2974 | + | |
| 2975 | + | |
| 2976 | + | |
| 2977 | + | |
2973 | 2978 | | |
2974 | 2979 | | |
2975 | | - | |
2976 | | - | |
| 2980 | + | |
| 2981 | + | |
| 2982 | + | |
2977 | 2983 | | |
2978 | 2984 | | |
2979 | 2985 | | |
| |||
0 commit comments