Meta's Immortal Objects: How Python Became 2% Slower but More Powerful

Meta's Immortal Objects: How Python Became 2% Slower but More Powerful

1.27KReads
25 August, 2023

In the world of programming, even the smallest changes can have a significant impact on the performance of a language.

And recently, the team at Meta made a change to Python that has made it 2% slower. But here's the twist - they are actually proud of it!

So What did they do? And Why??

Meta introduced the concept of immortal objects to Python. The idea is to have objects hold a DO_NOT_DELETE flag, which tells the garbage collector to ignore them during its rounds. Basically, when the garbage collector comes around to clean up unused objects, it simply ignores those with this flag.

Meta's Immortal Objects: How Python Became 2% Slower but More Powerful

Now, let's take a step back and understand how garbage collection works in Python. In Python, every object has a nifty feature called a reference counter. This counter keeps track of how many references exist to that object. When the counter hits zero, the garbage collector swoops in and deletes the object. This approach differs from other languages like Java or Golang, which use a mark and sweep algorithm to identify dead objects.

However, there's a catch with reference counting when it comes to sharing objects across threads.

Whenever an object is referenced, the counter increments. The problem arises when multiple threads try to access and modify the same object simultaneously. This operation is not thread-safe, leaving us with two options: copy on write or a global interpreter lock.

  • The first option, copy on write, involves creating a new copy of the object whenever a reference is added to it. This ensures that each thread has its own version of the object and can modify it without interfering with others. But, it can be wasteful in terms of memory usage.
  • The second option, global interpreter lock, requires taking a lock before making any changes to shared objects. This ensures that only one thread can access the object at a time, preventing conflicts. However, it significantly slows down the performance of multi-threaded applications.
Meta's Immortal Objects: How Python Became 2% Slower but More Powerful

Now, let's dive into Meta's solution. Instead of relying on copy on write or global interpreter lock, they made a groundbreaking change by defining objects as immutable. This means that the reference count variables of these objects are also immutable. As a result, the garbage collector can effortlessly ignore these objects during its rounds, allowing for efficient sharing across threads.

The impact of this change has been astounding. Meta has witnessed memory savings of more than 30% with this approach. However, there is a slight trade-off. The reference checks for these immutable objects still need to be performed in the critical sections of garbage collection, resulting in a small overhead cost of 2%.

So, why is Meta proud of making Python slower? Because this change unlocks a host of new possibilities for the language.

Python becomes a more powerful tool for developing multi-threaded applications, enabling smoother collaboration among threads. And that's definitely something worth celebrating!