Skip to content

Instantly share code, notes, and snippets.

@moreati
Last active March 2, 2022 22:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save moreati/7e5d4fe624083e12d04fa780230f3cfd to your computer and use it in GitHub Desktop.
Save moreati/7e5d4fe624083e12d04fa780230f3cfd to your computer and use it in GitHub Desktop.
from collections import namedtuple
from dataclasses import dataclass
from typing import NamedTuple
import pyperf
@dataclass
class DataclassPet:
legs: int
noise: str
@dataclass(frozen=True)
class DataclassFrozenPet:
legs: int
noise: str
@dataclass(slots=True)
class DataclassSlotsPet:
legs: int
noise: str
CollectionsNamedTuplePet = namedtuple("Pet", "legs noise")
class ClassPet:
legs: int
noise: str
def __init__(self, legs, noise) -> None:
self.legs = legs
self.noise = noise
def __repr__(self):
return f"<Pet legs={self.legs} noise='{self.noise}'>"
class TypingNamedTuplePet(NamedTuple):
legs: int
noise: str
if __name__ == '__main__':
runner = pyperf.Runner()
cases = [
('class', ClassPet),
('collections.namedtuple', CollectionsNamedTuplePet),
('dataclass frozen', DataclassFrozenPet),
('dataclass slots', DataclassSlotsPet),
('dataclass', DataclassPet),
('dict', dict),
('typing.NamedTuple', TypingNamedTuplePet),
]
for name, klass in cases:
dog = klass(legs=4, noise="woof")
runner.timeit(
name=name,
setup=f"dog = {klass.__name__}(legs=4, noise='woof')",
stmt="str(dog)",
globals={klass.__name__: klass},
)
--- bench_classes.py 2022-03-02 22:05:47.000000000 +0000
+++ bench_classes2.py 2022-03-02 22:05:22.000000000 +0000
@@ -51,7 +51,6 @@
dog = klass(legs=4, noise="woof")
runner.timeit(
name=name,
- setup=f"dog = {klass.__name__}(legs=4, noise='woof')",
- stmt="str(dog)",
+ stmt=f"dog = {klass.__name__}(legs=4, noise='woof'); str(dog)",
globals={klass.__name__: klass},
)
@moreati
Copy link
Author

moreati commented Mar 2, 2022

Replication of https://twitter.com/anthonypjshaw/status/1498913091492655111

$ python ../bench_classes.py
.....................
class: Mean +- std dev: 160 ns +- 2 ns
.....................
collections.namedtuple: Mean +- std dev: 229 ns +- 3 ns
.....................
dataclass frozen: Mean +- std dev: 430 ns +- 6 ns
.....................
dataclass slots: Mean +- std dev: 424 ns +- 5 ns
.....................
dataclass: Mean +- std dev: 430 ns +- 5 ns
.....................
dict: Mean +- std dev: 251 ns +- 2 ns
.....................
typing.NamedTuple: Mean +- std dev: 230 ns +- 5 ns

Python 3.10.2, on macOS 12.2.x, arm64

@moreati
Copy link
Author

moreati commented Mar 2, 2022

Including object initialisation

$ python ../bench_classes2.py
.....................
class: Mean +- std dev: 342 ns +- 3 ns
.....................
collections.namedtuple: Mean +- std dev: 411 ns +- 6 ns
.....................
dataclass frozen: Mean +- std dev: 753 ns +- 15 ns
.....................
dataclass slots: Mean +- std dev: 604 ns +- 14 ns
.....................
dataclass: Mean +- std dev: 640 ns +- 13 ns
.....................
dict: Mean +- std dev: 314 ns +- 3 ns
.....................
typing.NamedTuple: Mean +- std dev: 413 ns +- 8 ns

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