Python at Cognate Press
Python
Python, its runtimes, frameworks, and the systems beneath them — read from source, measured, not assumed.
Published as PyDepth at pydepth.com, written by Elliot Sayer — how Python behaves when you look underneath it. First issue .
Every issue on Python
Under a Latin-1 locale, CPython 3.13 reads a UTF-8 file as mojibake and raises nothing. 3.15 reads it correctly and raises on the Latin-1 file 3.13 read fine.
Importing logging before asyncio moves 5.5 ms from asyncio's line to logging's. The program does the same work. The cumulative column charges whoever got there first.
A lazy import of asyncio costs no measurable time and no modules at startup. Read the name once and 26.4 of the 26.8 ms come back. Deferral is not removal.
On CPython 3.10 a NamedTuple attribute read cost 0.81x a read through an instance dictionary. On 3.11 it costs 1.90x. Nothing about NamedTuple changed.
sys.getsizeof reports 296 bytes for a class's first instance dict and 96 once twenty-six exist. The instance itself costs 96 bytes and getsizeof says 48.
A read through __slots__ costs 24% more than one through an instance dictionary on CPython 3.13.2. Rebuild the same version and the gap goes away.
Annotations cost nothing per call and everything at import. Reading __annotations__ takes 24 ns; resolving the same class with get_type_hints takes 3.4 µs, 140x more.
Removing Django's entire default middleware chain saved 0.02 ms per request. Fixing one N+1 query on a fifty-row list view saved 3.30 ms.
Awaiting a coroutine that never suspends costs 53 ns against 24 ns for a plain call. Wrapping the same coroutine in a Task and awaiting it costs 28,958 ns.
Eight threads of pure-Python arithmetic run at 0.98x the speed of one. The same eight threads doing IO run at 7.90x. The GIL is a scheduler, and it has a dial.
Importing asyncio costs 21.9 ms and pulls in 100 modules. Importing email costs 0.1 ms and pulls in one. Granularity predicts import cost; size does not.
An instance with three attributes costs 96 bytes, not the 344 sys.getsizeof reports, and __slots__ read 12% slower on the CPython 3.13.2 build measured here.
The byline
Language behavior, concurrency and the trade-offs hidden beneath Python's deceptively simple surface. Measurements over folklore.
What the title covers
- Python
- CPython
- Global interpreter lock
- asyncio
- Import system
- Type hints
- Django
- SQLAlchemy
The other languages in the imprint: PHP · JavaScript · Java · C# · SQL · Go. Each has one title and one byline behind it — the index is at Topics.