Skip to content

Commit dfb576e

Browse files
committed
perf(core): improve perfomance of converting dataclasses to json
1 parent eba2c61 commit dfb576e

File tree

1 file changed

+14
-10
lines changed

1 file changed

+14
-10
lines changed

packages/core/src/robotcode/core/dataclasses.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,20 @@ def decode_case(type: Type[_T], name: str) -> str:
140140
return name
141141

142142

143+
NONETYPE = type(None)
144+
145+
__dataclasses_cache: Dict[Type[Any], Tuple[dataclasses.Field, ...]] = {} # type: ignore
146+
__handlers_cache: Dict[Type[Any], Callable[[Any, bool, bool], Any]] = {}
147+
148+
143149
def __default(o: Any) -> Any:
144150
if dataclasses.is_dataclass(o):
151+
t = type(o)
152+
fields = __dataclasses_cache.get(t, None)
153+
if fields is None:
154+
fields = dataclasses.fields(t)
155+
__dataclasses_cache[t] = fields
156+
145157
return {
146158
name: value
147159
for name, value, field in (
@@ -150,7 +162,7 @@ def __default(o: Any) -> Any:
150162
getattr(o, field.name),
151163
field,
152164
)
153-
for field in dataclasses.fields(o)
165+
for field in fields
154166
if (field.init or field.metadata.get("force_json", False)) and not field.metadata.get("nosave", False)
155167
)
156168
if value is not None or field.default == dataclasses.MISSING
@@ -366,21 +378,15 @@ def as_dict(
366378
return cast(Dict[str, Any], _as_dict_inner(value, remove_defaults, encode))
367379

368380

369-
NONETYPE = type(None)
370-
371-
372381
def _handle_basic_types(value: Any, _remove_defaults: bool, _encode: bool) -> Any:
373382
return value
374383

375384

376-
__dataclasses_cache: Dict[Type[Any], Tuple[dataclasses.Field, ...]] = {} # type: ignore
377-
378-
379385
def _handle_dataclass(value: Any, remove_defaults: bool, encode: bool) -> Dict[str, Any]:
380386
t = type(value)
381387
fields = __dataclasses_cache.get(t, None)
382388
if fields is None:
383-
fields = dataclasses.fields(value)
389+
fields = dataclasses.fields(t)
384390
__dataclasses_cache[t] = fields
385391
return {
386392
encode_case(t, f) if encode else f.name: _as_dict_inner(getattr(value, f.name), remove_defaults, encode)
@@ -442,8 +448,6 @@ def _handle_unknown_type(value: Any, _remove_defaults: bool, _encode: bool) -> A
442448
),
443449
]
444450

445-
__handlers_cache: Dict[Type[Any], Callable[[Any, bool, bool], Any]] = {}
446-
447451

448452
def _as_dict_inner(
449453
value: Any,

0 commit comments

Comments
 (0)