A ~2% slowdown in every python program everywhere sounds...unfortunate to say the least.
I read that as a ~2% slowdown in reference counting, or garbage collection in general.
I strongly doubt that. Adding a check to a simple increment instruction is likely slowing it down by more than 2x not 2% so it must be some whole program performance benchmark that's slowed by 2%.
The PEP says that a naïve implementation would cause a 4% performance hit and have a list of various ways of speeding up cases where immortality makes sense / is guaranteed that they say can bring this to parity. Maybe they implemented part of the list.
I was mostly curious if they accomplished this with some neat trick other than adding a check to every Py_INCREF and Py_DECREF to check for a magic value, which would be a performance overhead for all non-immortal objects, but it seems there's not much to see there--it's a 2% cost for normal use cases.
I've read through the PEP but I don't understand how I would implement this if I wanted to. Will there be some base class I can inherit from?
You don't, this is an internal implementation detail of CPython, the interpreter decides what objects are immortal, e.g. None