Improve performance when serializing small bits of JSON (#93653)

* Improve performance when serializing small bits of JSON

Making json_bytes a partial reduced the run time to
build the small JSON messages by ~18.75%

We serialize a lot of small messages over the websocket

* typing
This commit is contained in:
J. Nick Koston 2023-05-27 18:53:52 -05:00 committed by GitHub
parent c721cbd10c
commit 5feceee588
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,10 +2,11 @@
from collections import deque from collections import deque
from collections.abc import Callable from collections.abc import Callable
import datetime import datetime
from functools import partial
import json import json
import logging import logging
from pathlib import Path from pathlib import Path
from typing import Any, Final from typing import TYPE_CHECKING, Any, Final
import orjson import orjson
@ -55,6 +56,18 @@ def json_encoder_default(obj: Any) -> Any:
raise TypeError raise TypeError
if TYPE_CHECKING:
def json_bytes(obj: Any) -> bytes:
"""Dump json bytes."""
else:
json_bytes = partial(
orjson.dumps, option=orjson.OPT_NON_STR_KEYS, default=json_encoder_default
)
"""Dump json bytes."""
class ExtendedJSONEncoder(JSONEncoder): class ExtendedJSONEncoder(JSONEncoder):
"""JSONEncoder that supports Home Assistant objects and falls back to repr(o).""" """JSONEncoder that supports Home Assistant objects and falls back to repr(o)."""
@ -75,13 +88,6 @@ class ExtendedJSONEncoder(JSONEncoder):
return {"__type": str(type(o)), "repr": repr(o)} return {"__type": str(type(o)), "repr": repr(o)}
def json_bytes(data: Any) -> bytes:
"""Dump json bytes."""
return orjson.dumps(
data, option=orjson.OPT_NON_STR_KEYS, default=json_encoder_default
)
def _strip_null(obj: Any) -> Any: def _strip_null(obj: Any) -> Any:
"""Strip NUL from an object.""" """Strip NUL from an object."""
if isinstance(obj, str): if isinstance(obj, str):
@ -119,9 +125,7 @@ def json_dumps(data: Any) -> str:
with option |= orjson.OPT_PASSTHROUGH_DATACLASS and it with option |= orjson.OPT_PASSTHROUGH_DATACLASS and it
will fallback to as_dict will fallback to as_dict
""" """
return orjson.dumps( return json_bytes(data).decode("utf-8")
data, option=orjson.OPT_NON_STR_KEYS, default=json_encoder_default
).decode("utf-8")
def json_dumps_sorted(data: Any) -> str: def json_dumps_sorted(data: Any) -> str: