Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save amirsoroush/3d16647ced33f46aceb0c4d7446134b7 to your computer and use it in GitHub Desktop.
Save amirsoroush/3d16647ced33f46aceb0c4d7446134b7 to your computer and use it in GitHub Desktop.
Performance comparison between dataclass & namedtuple & regular classes
from dataclasses import dataclass
from time import perf_counter
from typing import NamedTuple
class Person:
def __init__(self, first_name: str, last_name: str, age: int) -> None:
self.first_name = first_name
self.last_name = last_name
self.age = age
class Person_slots:
__slots__ = ("first_name", "last_name", "age")
def __init__(self, first_name: str, last_name: str, age: int) -> None:
self.first_name = first_name
self.last_name = last_name
self.age = age
@dataclass
class PersonDC:
first_name: str
last_name: str
age: int
@dataclass(slots=True)
class PersonDC_slots:
first_name: str
last_name: str
age: int
@dataclass(frozen=True)
class PersonDC_Frozen:
first_name: str
last_name: str
age: int
@dataclass(frozen=True, slots=True)
class PersonDC_Frozen_Slots:
first_name: str
last_name: str
age: int
class Person_NT(NamedTuple):
first_name: str
last_name: str
age: int
all_classes = (
Person,
Person_slots,
PersonDC,
PersonDC_slots,
PersonDC_Frozen,
PersonDC_Frozen_Slots,
Person_NT,
)
n = 2_000_000
def create_instances_and_timeit(cls):
start = perf_counter()
for _ in range(n):
cls("foo", "boo", 20)
finish = perf_counter() - start
print(f"{f'Creation using {cls.__name__} took':<60}: {finish:.5f}")
def access_attribute_and_timeit(instance):
start = perf_counter()
for _ in range(n):
instance.first_name
finish = perf_counter() - start
cls_name = type(instance).__name__
print(f"{f'Accessing attribute using {cls_name} took':<60}: {finish:.5f}")
def test_creation():
for c in all_classes:
create_instances_and_timeit(c)
def test_attribute_access():
for c in all_classes:
access_attribute_and_timeit(c("foo", "boo", 20))
if __name__ == "__main__":
test_creation()
print("-----------------------------------")
test_attribute_access()
@amirsoroush
Copy link
Author

And here is the result:

Creation using Person took:                            0.48808
Creation using Person_slots took:                      0.38520
Creation using PersonDC took:                          0.48939
Creation using PersonDC_slots took:                    0.37644
Creation using PersonDC_Frozen took:                   1.04712
Creation using PersonDC_Frozen_Slots took:             0.94524
Creation using Person_NT took:                         0.44121
-----------------------------------
Accessing attribute using Person took:                 0.07130
Accessing attribute using Person_slots took:           0.06953
Accessing attribute using PersonDC took:               0.07198
Accessing attribute using PersonDC_slots took:         0.07126
Accessing attribute using PersonDC_Frozen took:        0.07181
Accessing attribute using PersonDC_Frozen_Slots took:  0.07066
Accessing attribute using Person_NT took:              0.06895

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment