Repository navigation
Commit 60eca2d
Long ASCII runs now OR eight aligned words and test the high bits once,
one branch per 64 bytes (32 on 32-bit) instead of one per word. When
a block contains a non-ASCII byte, the existing one-word loop finds it.
It is plain C: GCC and Clang compile it to SSE2/NEON loads, other
compilers to ORed word loads with the same single branch.
Multiple compiler and architecture codegen sample: https://godbolt.org/z/8bM83vx3a
pyperf, PGO+LTO, 2 interleaved rounds:
| Benchmark | main | this |
|---|---:|---:|
| (b'a' * 4096).decode() | 165 ns | 108 ns: 1.53x faster |
| (b'a' * 200).decode() | 28.9 ns | 26.5 ns: 1.09x faster |
| b'a' * 200 + 'é' + ..., .decode() | 60.9 ns | 56.0 ns: 1.09x faster |
| b'a' * 136 + 'é' + ..., .decode() | 53.8 ns | 51.3 ns: 1.05x faster |
| 8-100 byte decodes, 'é' within 100 | | within 1.2 ns |
```python
import pyperf
runner = pyperf.Runner()
tail = 'é'.encode() + b'a' * 50
for n in (8, 100, 200, 4096):
runner.timeit(f"(b'a' * {n}).decode()", "s.decode()",
globals={"s": b'a' * n})
for n in (16, 100, 136, 200):
runner.timeit(f"(b'a' * {n} + 'é'.encode() + b'a' * 50).decode()",
"s.decode()", globals={"s": b'a' * n + tail})
```
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Victor Stinner <vstinner@python.org>
1 parent edd6f76 commit 60eca2d
2 files changed
Lines changed: 12 additions & 0 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 | |
|---|---|---|---|
| |||
5063 | 5063 | | |
5064 | 5064 | | |
5065 | 5065 | | |
| 5066 | + | |
| 5067 | + | |
| 5068 | + | |
| 5069 | + | |
| 5070 | + | |
| 5071 | + | |
| 5072 | + | |
| 5073 | + | |
| 5074 | + | |
| 5075 | + | |
5066 | 5076 | | |
5067 | 5077 | | |
5068 | 5078 | | |
| |||
0 commit comments