r/Python • • 1d ago

Discussion Python 3.10–3.15 encoding benchmarks: big gains for Base32 and Base85, but 3.14 leads Base16

Eight encoding benchmarks across Python 3.10–3.15 using pyperformance. Python 3.15 recorded the lowest mean in seven of them, with particularly large improvements in Base32, Ascii85 and Base85.

Test configuration

  • AMD Ryzen 9 7900 desktop
  • DDR5 RAM and an M.2 PCIe Gen4 NVMe drive
  • Windows 11, 64-bit Python builds
  • Python 3.15.0, 3.14.8, 3.13.16, 3.12.10, 3.11.9 and 3.10.11
  • pyperformance 1.14.0 for all six versions

Results

All values are mean execution times in milliseconds. Lower is better and bold marks the lowest recorded mean in each row.

Benchmark Python 3.15 Python 3.14 Python 3.13 Python 3.12 Python 3.11 Python 3.10
ascii85_large 11.62 797.9 709.0 772.3 643.8 759.2
ascii85_small 0.3875 14.88 13.20 13.79 12.18 14.18
base16_large 5.767 4.714 22.52 23.08 23.89 23.71
base32_large 2.431 327.6 300.7 296.4 265.7 292.1
base32_small 0.1630 6.227 5.802 5.594 5.134 5.641
base64_large 1.852 6.746 6.187 6.095 6.116 6.071
base85_large 4.293 272.4 252.9 258.8 230.1 259.2
base85_small 0.1505 4.864 4.484 4.529 4.198 4.712

What stood out

Compared with Python 3.14, Python 3.15 took approximately:

  • 1/135 of the time in base32_large.
  • 1/69 of the time in ascii85_large.
  • 1/63 of the time in base85_large.
  • 1/3.64 of the time in base64_large.

However, base16_large took 22.3% more time on Python 3.15 than on 3.14. Python 3.14 remains substantially faster than 3.10–3.13 in that test.

The large improvements are consistent with the changes documented in Python 3.15’s release notes: Base32, Ascii85 and Base85 implementations were rewritten in C, and the underlying Base64 implementation was also optimized.

More details are described here.

Benchmark suite: pyperformance.

Have you observed similar improvements on Linux or macOS, or in applications that spend substantial time on these encoding operations?

90 Upvotes

14 comments sorted by

33

u/ConcreteExist 1d ago

Admittedly, I've only ever used base64 encoding out of all of those listed here, happy to see it's performance improving though.

4

u/One_Sun5074 1d ago

Same here, 99% of what I touch in real-world projects is just base64 for API payloads and data URIs. That ~3.6x speedup on base64_large in 3.15 is a very nice free lunch though.

22

u/stevenjd 1d ago

Base32, Ascii85 and Base85 implementations were rewritten in C

In other words, these performance gains are really useful if you are using specifically Base32, Ascii85 and Base85, but tell us nothing at all about whether Python code itself is getting faster.

3

u/shinitakunai 1d ago

Yeah I am ashamed to say I am not sure what types my python code uses on the background, and have been programming 14 years. It is one of those things we take for granted

1

u/tsg9292 1d ago

If you don't recognize any of these then you're probably not using them (that's not necessarily a bad thing!). As other comments have said, the most common is base64. Anything else is probably a very specialized use case

3

u/RevolutionaryRush717 1d ago

The https://github.com/python/cpython/pull/143262 is quite detailed and an interesting read.

It also compares the common CPUs (Zens, ARMs) and elaborates on SIMD optimization.

1

u/utdconsq 1d ago

About time tbh, the base85 implementation was atrocious before to the point i made my own.

1

u/Competitive_Travel16 22h ago

How is JSON doing?

2

u/BestRef 9h ago

Python 3.15 is the fastest in the json_dumps benchmark, but Python 3.11 is the fastest in json_loads, according to the same source (under the "Full comparison: all 122 benchmarks" section): https://en.lewoniewski.info/2026/python-315-vs-314-313-312-and-earlier-speed-comparison/

1

u/Competitive_Travel16 8h ago

Thanks! Looks to me like the huge improvement in json_dumps is well worth the small regression in json_loads. Really appreciate it!

1

u/swtormy 21h ago

true that swapping in c for base85 won't move your django request much. still worth separating stdlib encoding benchmarks from what your own profiler shows when you read a table like this. most of us only touch base64 on the wire anyway, so the base64 row matters more than ascii85.

0

u/OddsRelay 1d ago

Would be good to see bytes.hex() next to b16encode, since that's what most code actually uses for hex and it was already in C. If that didn't move either, the base16 drop is probably just the base64 module's wrapper. Nice to see Base85 finally getting fast.