Created
May 20, 2023 21:37
-
-
Save amirsoroush/3d16647ced33f46aceb0c4d7446134b7 to your computer and use it in GitHub Desktop.
Performance comparison between dataclass & namedtuple & regular classes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
And here is the result: