Speed Up Your Python classes with slot
Tags: datastrucutre, python, algorithms, coding
Published: 2022-05-08 15:08:20

---
title: Speed Up Your Python classes with slot
published: true
date: 2022-05-08 14:56:25 UTC
tags: datastrucutre,python,algorithms,coding
canonical_url: 
---

![](https://cdn-images-1.medium.com/max/1024/1*TYy1xT2i_9NreYlNSd5KcA.png)

The special attribute [\_\_slots\_\_](https://docs.python.org/3/reference/datamodel.html#slots) allows you to explicitly state which instance attributes you expect your object instances to have, with the expected results:

1. **faster** attribute access.
2. **space savings** in memory.

The space savings is from

1. Storing value references in slots instead of \_\_dict\_\_.
2. Denying [\_\_dict\_\_](https://docs.python.org/3/library/stdtypes.html#object. __dict__ ) and \_\_weakref\_\_ creation if parent classes deny them and you declare \_\_slots\_\_.

When we create an object from a class, the attributes of the object will be stored in a dictionary called \_\_dict\_\_. We use this dictionary to get and set attributes. It allows us to dynamically create new attributes after the creation of the object.

Let’s create a simple class Person that initially has 2 attributes first\_name and last\_name. If we print out \_\_dict\_\_ of the object, we will get the key and value of each attribute. Meanwhile, we also print \_\_dict\_\_ of the class which will be needed later. After that, a new attribute reviewer is added to the object, and we can see it in the updated \_\_dict\_\_.

```
class Person:
     def __init__ (self, first_name: str, last_name: str):
         self.first_name = first_name
         self.last_name = last_name

if __name__ == " __main__":
     person = Person("Chidozie", "Okafor")
     print(person. __dict__ )
  {'first_name': 'Chidozie', 'last_name': 'Okafor'}
    print(Person. __dict__ )
{' __module__': ' __main__', ' __doc__': None, ' __init__': <function __init__ at 0x10e9cd140>}
```

The issues with dictionary is memory consumption and also access dictionary involves hashing, Dictionary is in fact a hash map. The worst case of the [time complexity](https://wiki.python.org/moin/TimeComplexity) of _get/set_ in a hash map is O(n).

**slots** provide a special mechanism to reduce the size of objects.It is a concept of memory optimisation on objects.

As every object in Python contains a dynamic dictionary that allows adding attributes. For every instance object, we will have an instance of a dictionary that consumes more space and wastes a lot of RAM. In Python, there is no default functionality to allocate a static amount of memory while creating the object to store all its attributes.  
Usage of \_\_slots\_\_ reduce the wastage of space and speed up the program by allocating space for a fixed amount of attribute

To create a slot, all we need to do is to add \_\_slots\_\_ field or slots=True if we are using dataclass.

```
class PersonSlot:
     __slots__ = ["first_name", "last_name"]
     def __init__ (self, first_name: str, last_name: str):
         self.first_name = first_name
         self.last_name = last_name

if __name__ == " __main__":
     person = Person("Chidozie", "Okafor")
     print(person. __dict__ )
  {'first_name': 'Chidozie', 'last_name': 'Okafor'}
    print(Person. __dict__ )
{' __module__': ' __main__', ' __slots__': ['first_name', 'last_name'], ' __init__': <function __init__ at 0x10432b140>, ' __doc__': None}
```

To avoid repetition of variable names, we can use dataclasses to create a class that will automatically create slots for us.

```
from dataclasses import dataclass

@dataclass(slots=True)
class PersonSlot:
      first_name: str
      last_name: str

if __name__ == " __main__":
   person = PersonSlot("Chidozie", "Okafor")
   print(person. __dict__ )
   print(PersonSlot. __dict__ )
```

#### **Advantages of using slots:**

1. Slots are faster than \_\_dict\_\_.
2. Slots are more memory efficient.
3. Slots are more secure.
4. Slots are more convenient.
5. Slots are more readable.
6. Slots are more efficient.

#### Disadvantages of using slots:

1. Slots are not compatible with Multiple inheritance and Mixins.
2. Slots are not compatible with metaclasses.
3. Slots are not compatible with ABCs.
4. Slots are not compatible with pickling.
5. Slots are not compatible with copy.
6. Slots are not compatible with deepcopy.

#### Let’s see how fast slots are compare to normal dictionary.

```
import timeit
from dataclasses import dataclass
from functools import partial

@dataclass(slots=False)
class Person:
    first_name : str
    last_name: str

@dataclass(slots=True)
class PersonSlot:
    first_name : str
    last_name : str

def get_set_delete(person: Person | PersonSlot):
     person.first_name = "Raphael"
     _ = person.first_name
     del person.first_name

def get_percentage_of_performance():
    person = Person("Chidozie", "Okafor")
    person_slot = PersonSlot("Chidozie", "Okafor")
    no_slots = min(timeit.repeat(partial(get_set_delete, person), number=100, repeat=3))
    slots = min(timeit.repeat(partial(get_set_delete, person_slot), number=100, repeat=3))
    print(f"No Slots: {no_slots}") No Slots: 3.3914000596269034e-05

print(f"Slots: {slots}") Slots: 1.8151000404031947e-05
    print(f"Percentage of performance: {(slots / no_slots) * 100}") Percentage of performance: 53.520670180175635

if __name__ == " __main__":
    get_percentage_of_performance()
```

There are so many things we can do with slots to help improve the speed of our code. try as many as possible and share with others.

Happy coding!!!!