GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||
GeezerVison is showing github.com — gh-160931: Speed up bytes construction from exact bytes and int by cmaloney · Pull Request #160934 · python/cpython Conversation
|
| 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()")
Sorry, something went wrong.
There was an error while loading. Please reload this page.
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 <[email protected]>
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.