mirror of https://github.com/zulip/zulip.git
tornado: Replace dataclasses.asdict() call, as it is slow.
This code is called in the hot path when Tornado is processing events. As such, making this code performant is important. Profiling shows that a significant portion of the time is spent calling asdict() to serialize the UserMessageNotificationsData dataclass. In this case `asdict` does several steps which we do not need, such as attempting to recurse into its fields, and deepcopy'ing the values of the fields. In our use case, these add a notable amount of overhead: ```py3 from zerver.tornado.event_queue import UserMessageNotificationsData from dataclasses import asdict from timeit import timeit o = UserMessageNotificationsData(1, False, False, False, False, False, False, False, False, False, False, False) %timeit asdict(o) %timeit {**vars(o)} ``` Replace the `asdict` call with a direct access of the fields. We perform a shallow copy because we do need to modify the resulting fields.
This commit is contained in:
parent
ed069ebe0e
commit
6427d85cf6
|
@ -9,7 +9,6 @@ import traceback
|
|||
import uuid
|
||||
from collections import deque
|
||||
from contextlib import suppress
|
||||
from dataclasses import asdict
|
||||
from functools import lru_cache
|
||||
from typing import (
|
||||
AbstractSet,
|
||||
|
@ -987,7 +986,11 @@ def process_message_event(
|
|||
all_bot_user_ids=all_bot_user_ids,
|
||||
)
|
||||
|
||||
internal_data = asdict(user_notifications_data)
|
||||
# Calling asdict would be slow, as it does a deep copy; pull
|
||||
# the attributes out directly and perform a shallow copy, as
|
||||
# we do intend to adjust the dict.
|
||||
internal_data = {**vars(user_notifications_data)}
|
||||
|
||||
# Remove fields sent through other pipes to save some space.
|
||||
internal_data.pop("user_id")
|
||||
internal_data["mentioned_user_group_id"] = mentioned_user_group_id
|
||||
|
|
Loading…
Reference in New Issue