Last active
December 8, 2024 22:45
-
-
Save rnag/bffd90092fdbcb5f5f3ea2a3b331e140 to your computer and use it in GitHub Desktop.
Dataclass Wizard vs. Other De/Serialization Libraries!
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
# pip install apischema | |
# pip install dataclass-wizard | |
from dataclasses import dataclass, field | |
from timeit import timeit | |
from uuid import UUID, uuid4 | |
from apischema import deserialize, serialize | |
from dataclass_wizard import JSONWizard | |
# Define a schema with standard dataclasses | |
@dataclass | |
class Resource: | |
id: UUID | |
name: str | |
tags: set[str] = field(default_factory=set) | |
@dataclass | |
class Resource2(JSONWizard): | |
class _(JSONWizard.Meta): | |
# with upcoming `v1`, this will be even faster! | |
# Follow for more: https://github.com/rnag/dataclass-wizard/discussions/165 | |
v1 = False | |
id: UUID | |
name: str | |
tags: set[str] = field(default_factory=set) | |
# Get some data | |
uuid = uuid4() | |
data = {"id": str(uuid), "name": "wyfo", "tags": ["some_tag"]} | |
n = 100_000 | |
print('apischema: ', timeit('deserialize(Resource, data)', globals=globals(), number=n)) | |
print('dataclass-wizard: ', timeit('Resource2.from_dict(data)', globals=globals(), number=n)) | |
# Deserialize data | |
resource = deserialize(Resource, data) | |
resource2 = Resource2.from_dict(data) | |
# Results (current): | |
# apischema: 0.2984417909756303 | |
# dataclass-wizard: 0.1650990409834776 | |
# Results (with upcoming `v1`): | |
# apischema: 0.31923512497451156 | |
# dataclass-wizard: 0.11814916698494926 | |
assert resource == Resource(uuid, "wyfo", {"some_tag"}) | |
assert resource2 == Resource2(uuid, "wyfo", {"some_tag"}) | |
# Serialize objects | |
assert serialize(Resource, resource) == data |
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 timeit import timeit | |
from dacite import from_dict | |
from dataclass_wizard import fromdict, LoadMeta | |
from pydantic.dataclasses import dataclass as py_dataclass | |
@dataclass | |
class User: | |
name: str | |
age: int | |
is_active: bool | |
@py_dataclass | |
class UserModel: | |
name: str | |
age: int | |
is_active: bool | |
data = { | |
'name': 'john', | |
'age': 30, | |
'is_active': True, | |
} | |
n = 100_000 | |
# setup: pip install dacite | |
# dacite: 0.303 | |
# setup: git clone -b feature/performance-improvements https://github.com/konradhalas/dacite.git && cd dacite && pip install -e . | |
# dacite: ?? | |
print('dacite: ', timeit('from_dict(data_class=User, data=data)', | |
globals=globals(), number=n)) | |
# setup: pip install pydantic | |
# pydantic: 0.100 | |
print('pydantic: ', timeit('UserModel(**data)', | |
globals=globals(), number=n)) | |
# setup: pip install dataclass-wizard | |
# With upcoming `v1`, the `dataclass-wizard` will be even faster! | |
# LoadMeta(v1=True).bind_to(User) | |
# dataclass-wizard: 0.075 | |
print('dataclass-wizard: ', timeit('fromdict(User, data)', | |
globals=globals(), number=n)) | |
user = from_dict(data_class=User, data=data) | |
assert user == User(name='john', age=30, is_active=True) | |
user = UserModel(**data) | |
assert user == UserModel(name='john', age=30, is_active=True) | |
user = fromdict(User, data) | |
assert user == User(name='john', age=30, is_active=True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment