Skip to content

Instantly share code, notes, and snippets.

@samuelcolvin
Created January 17, 2024 13:57
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 samuelcolvin/0b7e08f6358d602bb3f7b74b7109fc6e to your computer and use it in GitHub Desktop.
Save samuelcolvin/0b7e08f6358d602bb3f7b74b7109fc6e to your computer and use it in GitHub Desktop.
import json
import random
import uuid
from datetime import date
import timeit
from typing import TypeVar, Generic
import pydantic_core
from pydantic import BaseModel
class PModel(BaseModel):
field1: str
field2: str
field3: int | None = None
field4: int | None = None
field5: int | None = None
field6: int | None = None
field7: int | None = None
field8: uuid.UUID | None = None
field9: uuid.UUID | None = None
field10: bool | None = None
field11: int | None = None
field12: str | None = None
field13: str | None = None
field14: bool | None = None
# field15: IdModel
id: str
uuid: uuid.UUID
field16: str | None = None
field17: float | None = None
field18: date | None = None
P = TypeVar('P')
class Result(BaseModel, Generic[P]):
id: int
uuid: uuid.UUID
properties: P
class Response(BaseModel, Generic[P]):
results: list[Result[P]]
# debug(Response[PModel].__pydantic_core_schema__)
def rand_str():
return ''.join(random.choice('abcdefghijklmnopqrstuvwxyz') for i in range(random.randint(1, 10)))
def rand_num():
return random.randint(1, 1_000)
def gen_p():
return {
'field1': rand_str(),
'field2': rand_str(),
'field3': rand_num(),
# skip half of the optional fields
'field5': rand_num(),
'field7': rand_num(),
'field9': str(uuid.uuid4()),
'field10': True,
'field12': rand_str(),
'field14': False,
'id': rand_str(),
'uuid': str(uuid.uuid4()),
}
def gen_result():
return {
'id': rand_num(),
'uuid': str(uuid.uuid4()),
'properties': gen_p(),
}
def gen_response():
return {'results': [gen_result() for _ in range(1000)]}
json_data = json.dumps(gen_response()).encode()
timer = timeit.Timer(
'Response[PModel].model_validate_json(json_data)',
globals={'Response': Response, 'PModel': PModel, 'json_data': json_data},
)
n, t = timer.autorange()
print(f'model_validate_json(...): {t / n * 1_000:.2f}ms')
timer = timeit.Timer(
'Response[PModel].model_validate(json.loads(json_data))',
globals={'Response': Response, 'PModel': PModel, 'json_data': json_data, 'json': json},
)
n, t = timer.autorange()
print(f'model_validate(json.loads(...)): {t / n * 1_000:.2f}ms')
timer = timeit.Timer('json.loads(json_data)', globals={'json_data': json_data, 'json': json})
n, t = timer.autorange()
print(f'json.loads(...): {t / n * 1_000:.2f}ms')
timer = timeit.Timer(
'pydantic_core.from_json(json_data)', globals={'json_data': json_data, 'pydantic_core': pydantic_core}
)
n, t = timer.autorange()
print(f'pydantic_core.from_json(...): {t / n * 1_000:.2f}ms')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment