Skip to content

postgrest.types.JSONAdapter is much slower than TypeAdapter(JsonValue) #1486

Description

@coroluca

Describe the bug

Hi, I noticed that the JSON alias currently used by postgrest-py:

JSON = TypeAliasType(
    "JSON",
    "Union[None, bool, str, int, float, Sequence[JSON], Mapping[str, JSON]]",
)

is much slower (13x) than Pydantic's built-in JsonValue on the same payload.

Reproduction

import json
import statistics
import timeit

from postgrest.types import JSONAdapter
from pydantic import TypeAdapter
from pydantic.types import JsonValue

postgrest_json = JSONAdapter
json_value = TypeAdapter(JsonValue)

payload = json.dumps(
    [
        {
            "id": i,
            "name": f"doc-{i}",
            "labels": ["a", "b", "c"],
            "status": {"id": 1, "label": "Review", "done": False},
            "metadata": {"scores": [0.9, 0.8, 0.7], "flags": {"pinned": True, "archived": False}},
        }
        for i in range(1_000)
    ]
).encode()


def bench(label: str, stmt: str) -> float:
    ms = statistics.mean(timeit.repeat(stmt, number=1, repeat=5, globals=globals())) * 1000
    print(f"{label:24} {ms:8.2f} ms")
    return ms


print(f"payload_size={len(payload):,} bytes")
bench("postgrest TypeAliasType", "postgrest_json.validate_json(payload)")
bench("pydantic.JsonValue", "json_value.validate_json(payload)")
bench("json.loads", "json.loads(payload)")

On my machine this is the output:


payload_size=200,780 bytes
postgrest TypeAliasType     11.65 ms
pydantic.JsonValue           0.86 ms
json.loads                   0.76 ms

Steps to reproduce

No response

Library affected

postgrest

Library version

postgrest 2.29.0

Python version

3.14.0

Metadata

Metadata

Assignees

Labels

PostgRESTIssues related to postgrest-pybugSomething isn't workingpythonPull requests that update Python code

Type

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions