Created
July 28, 2024 16:00
-
-
Save MtkN1/cbc42fb29565a854b6683ac3981ec576 to your computer and use it in GitHub Desktop.
pydantic vs. cattrs performance
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
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import json\n", | |
"import urllib.request\n", | |
"from dataclasses import dataclass\n", | |
"from typing import TypeAlias, TypedDict\n", | |
"\n", | |
"import orjson\n", | |
"import pydantic_core\n", | |
"from attrs import define\n", | |
"from cattrs import structure\n", | |
"from pydantic import BaseModel, TypeAdapter\n", | |
"\n", | |
"url = \"https://jsonplaceholder.typicode.com/posts\"\n", | |
"\n", | |
"with urllib.request.urlopen(url) as response:\n", | |
" json_content = response.read()\n", | |
"\n", | |
"\n", | |
"class TypedDictPost(TypedDict):\n", | |
" userId: int\n", | |
" id: int\n", | |
" title: str\n", | |
" body: str\n", | |
"\n", | |
"\n", | |
"TypedDictPosts: TypeAlias = list[TypedDictPost]\n", | |
"\n", | |
"\n", | |
"@dataclass\n", | |
"class DataclassPost:\n", | |
" userId: int\n", | |
" id: int\n", | |
" title: str\n", | |
" body: str\n", | |
"\n", | |
"\n", | |
"DataclassPosts: TypeAlias = list[DataclassPost]\n", | |
"\n", | |
"\n", | |
"@define\n", | |
"class AttrsPost:\n", | |
" userId: int\n", | |
" id: int\n", | |
" title: str\n", | |
" body: str\n", | |
"\n", | |
"\n", | |
"AttrsPosts: TypeAlias = list[AttrsPost]\n", | |
"\n", | |
"\n", | |
"class PydanticPost(BaseModel):\n", | |
" userId: int\n", | |
" id: int\n", | |
" title: str\n", | |
" body: str\n", | |
"\n", | |
"\n", | |
"PydanticPosts = TypeAdapter(list[PydanticPost])" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"113 μs ± 12.9 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n", | |
"136 μs ± 18.7 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n", | |
"34.4 μs ± 1.73 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n" | |
] | |
} | |
], | |
"source": [ | |
"# Parse Any JSON\n", | |
"%timeit json.loads(json_content)\n", | |
"%timeit pydantic_core.from_json(json_content)\n", | |
"%timeit orjson.loads(json_content)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"91.3 μs ± 15.8 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n", | |
"112 μs ± 4.29 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n", | |
"132 μs ± 23.2 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n" | |
] | |
} | |
], | |
"source": [ | |
"# Parse JSON with cattrs \n", | |
"%timeit structure(orjson.loads(json_content), TypedDictPosts)\n", | |
"%timeit structure(orjson.loads(json_content), DataclassPosts)\n", | |
"%timeit structure(orjson.loads(json_content), AttrsPosts)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"154 μs ± 5.66 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n", | |
"140 μs ± 20.1 μs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)\n" | |
] | |
} | |
], | |
"source": [ | |
"# Parse JSON with pydantic\n", | |
"%timeit PydanticPosts.validate_json(json_content)\n", | |
"%timeit PydanticPosts.validate_python(orjson.loads(json_content))" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": ".venv", | |
"language": "python", | |
"name": "python3" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 3 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython3", | |
"version": "3.12.4" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment